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. 旋转函数
思路:
找规律
所以对应的公式:
代码:
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;}
}