数组题目: 665. 非递减数列、453. 最小移动次数使数组元素相等、283. 移动零、189. 旋转数组、396. 旋转函数

665. 非递减数列

题解:

题目要求一个非递减数列,我们可以考虑需要更改的情况:

  • nums = {4, 2, 5}

对于这个nums,由于2的出现导致非递减,更改的情况就是要么4调到<=2,要么2调到4,5.

  • nums = {1, 4, 2, 5}

对于这个nums,由于2的出现导致非递减,更改的情况就是要么4调到1,,2,要么2调到4,5.

  • nums = {3, 4, 2, 5}

对于这个nums,由于2的出现导致非递减,更改的情况就是2调到4,5.

所以算法就是:

如果按照1的情况,当i = 1,那么直接就把nums[i - 1]改成nums[i],nums[i]不动

如果按照2的情况,当nums[i - 2] < nums[i],那我们就优先考虑把nums[i - 1] 调小到 >= nums[i - 2] 并且 <= nums[i]

如果按照1的情况,nums[i - 2] > nums[i],那我们就调整nums[i],让nums[i] = nums[i - 1]。

代码:

class Solution {
    public boolean checkPossibility(int[] nums) {
        int count = 0;//统计需要满足非递减的次数
        for(int i = 1; i < nums.length;i++){
            if(nums[i] < nums[i - 1]){
                if(i == 1 || nums[i] >= nums[i - 2]){// i=1就是第一个情况,后面的是第二种
                    nums[i - 1] = nums[i];
                }else{
                    nums[i] = nums[i - 1];
                }
                count++;
            }
        }
        return count <= 1;
    }
}

453. 最小移动次数使数组元素相等

思路:

题目要求我们每次操作将会让n-1个元素增加1,来满足要求。我们可以反过来思考,找到最小的数,遍历其他的数,累加所有元素和最小的元素的差距。

代码:

class Solution {
    public int minMoves(int[] nums) {
        int minNum = Arrays.stream(nums).min().getAsInt();
        int res = 0;
        for(int num : nums){
            res += num - minNum;
        }
        return res;
    }
}

283. 移动零

思路:(双指针)

我们定义两个指针left, right都等于0,遍历nums,如果nums[right] != 0,那我们就让nums[left]和nums[right]进行交换,再把Left增加。如果等于0,那就让right++。

其实Left就是第一个0的位置,right就是让他找到不为0的地方。


189. 旋转数组

思路:

  • 第一步:先翻转数组里的数
  • 第二步:翻转前[0, k - 1]个数
  • 第三步:翻转后面[k, n]的数

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }

    public void reverse(int[] nums, int left, int right){
        while(left <= right){
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }
}

396. 旋转函数

思路:

找规律

所以对应的公式:

F[i] = F[i - 1] + sum - n * nums[n - i];

代码:

class Solution {
    public int maxRotateFunction(int[] nums) {
        int sum = 0, f = 0, n = nums.length, ans = 0;
        for(int i = 0; i < n; i++){
            sum += nums[i];
            f += i * nums[i];//f(0);
        }
        ans = f;
        for(int i = 1; i < n; i++){
            f = f + sum - n * (nums[n - i]);//f[i] = f[i - 1] + sum -n * nums[n - i];
            ans = Math.max(ans, f);
        }
        return ans;
    }
}

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值