665. 非递减数列
题目:
给你一个长度为 n 的整数数组,请你判断在最多改变 1 个元素的情况下,该数组能否变成一个非递减数列。
我们是这样定义一个非递减数列的: 对于数组中任意的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。
思路:
维持一个非递减数列,遇到递减的情况时(nums[I -1] > nums[i]),要么将前面的元素缩小,要么将后面的元素放大。
但是本题唯一的易错点就在这,
如果将nums[i]缩小,可能会导致其无法融入前面已经遍历过的非递减子数列;比如:[3,5,2,4],把5缩小 <=2 则会小于前面3变成递减数列。
如果将nums[i + 1]放大,可能会导致其后续的继续出现递减;把2放大 >=5 则会大于后面的4继续递减。
所以采取贪心算法,在遍历时,每次需要看连续的三个元素,也就是瞻前顾后。
分3种情况:
1、不存在下降的情况,即下降次数为0,返回true。
2、只出现了1次下降,将下降后的元素记为numsi
这时候可以尝试将nums[i - 1]变小,或者将nums[i]变大,已达到“非递减”的目的。
如果i = 1 或者 i = n-1,只需要将nums中第一个元素减小或者最后一个元素变大总能满足要求;
如果1 < i < n-1, 若将nums[i]变大,必须要求nums[i-1]<=nums[i+1],
若将nums[i-1]变小,必须要求nums[i-2]<=nums[i]
3、出现超过1次的下降,肯定不只通过调整一个元素完成要求,直接返回false
代码:
class Solution {
public boolean checkPossibility(int[] nums) {
int n = nums.length;
if (n <= 1){
return true;
}
//改变元素次数
int count = 0;
for(int i = 1; i< n; i++){
//不满足非递减数列条件
if(nums[i - 1] > nums[i]){
count++;
//改变次数大于1,直接返回false
if(count > 1){
return false;
}
//如果1 < i < n - 1时
if( i > 1 && i < n - 1 && nums[i - 2] > nums[i] && nums[i - 1] > nums[i + 1]){
return false;
}
}
}
return true;
}
}
转载:
如有冒犯请私信我删除
链接:https://leetcode.cn/problems/non-decreasing-array/solution/tan-xin-jie-xi-xia-jiang-zhi-duo-chu-xia-by3d/