题目详情
给你一个长度为 n 的整数数组,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。
我们是这样定义一个非递减数列的: 对于数组中任意的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/non-decreasing-array
解法思路
思路一:
思路分析
* 解题思路:什么样的数列才能够最多改变一个值的情况下
* 变为非递减呢?
* 我们观察发现如果在数组中,第i个值比第i+1个值大的情
* 况出现次数小于等于一次,那么这个数组就有可能满足改
* 变一个值成为非递减数列。
* 首先没有这种情况出现时,已经是非递减数列;当出现这
* 种情况多于一次时,至少需要改两个值才行。所以我们可
* 以遍历统计这种情况出现的次数,如果出现多于一次,直
* 接return false
* 那么只出现一次的情况需要改几个值能满足呢?笔者的思
* 路是,进行正向遍历,对于出现这种情况的第i个元素,他
* 是比后一个大,也比前一个大的,笔者把这个元素变为第i
* -1个元素的值,这样就不会比前面的元素小,但是这样一
* 定能满足吗?不一定!例如:[3,4,2,2],把4变为3后也不
* 行因为比后面大;如果变为前一个元素不行,那么就变成后
* 一个元素吧,只有这两种极端选择了,变为[3,2,2,2]呢?
* 很显然也不行,所以流程有了:
* 1.正向遍历,先把第i个元素变为第i-1个元素,设立flag
* 2.接着,第一种方案行不通后将第i个元素变为第i+1个元
* 素,成功就返回true,失败则返回false
代码
class Solution {
public boolean checkPossibility(int[] nums) {
//首先进行遍历筛选,只有数组中后一个比前一个大的个数小于等于1的
//数组才可能变为递减数列
int num_ill = 0;
boolean flag1 = false;
boolean flag2 = false;
int item;
for(int i = 0;i<nums.length-1;i++){
if(nums[i]>nums[i+1]){num_ill++;}
}
if(num_ill==1){//满足条件进行判断
//先进行正向判断,对于正向不满足的把第i-1个元素变为第i-2个元素
//的值,如果改变后满足了就可
for(int i = 0;i<nums.length-1;i++){
if(nums[i]>nums[i+1])
{if(i!=0){item = nums[i-1];}
else{item = 0;}
if(item<=nums[i+1]){
flag1 = true;
}
//break;//只判断一次就退出
if(!flag1){
if(i!=nums.length-2){
item = nums[i+2];
if(item>=nums[i]){flag2 = true;}
}else{
flag2 = true;
}
}
break;
}
}
return flag1||flag2;
}
else if(num_ill == 0){return true;}
else{return false;}
}
}
方案分析
*该方案需要两次遍历,时间复杂度为O(n^2),可以考虑将第二次遍历
*放入第一次中,时间复杂度为O(n)
思路二
思路分析
* 基本思路同方案一,但是思路二发现对于数组[3,4,2,2],第二个位
* 置的2小于第0个位置的3,需要将这个值变为前一个值4;如果现在数
* 组变为[3,4,3,3],那么这个数组只需要把第1个位置的4变为3即可;
* 所以,总结出规律,对于i+1位置小于i-1位置的,需要更新第i+1个元
* 素为第i个位置的元素的值,这样才可以大于等于前一个位置,后续再
* 接着判断满不满足。此种方法可以很好的把遍历集成
代码
class Solution {
public boolean checkPossibility(int[] nums) {
int n = nums.length, cnt = 0;
for (int i = 0; i < n - 1; ++i) {
int x = nums[i], y = nums[i + 1];
if (x > y) {
cnt++;
if (cnt > 1) {
return false;
}
if (i > 0 && y < nums[i - 1]) {
nums[i + 1] = x;
}
}
}
return true;
}
}
方案分析
*该方案并没有像方案一那样,上来就开始变值判断,而是总结出了需
*要和不需要判断的条件,即第i+1个值对比第i-1个值的关系,比较巧
*妙,时间复杂度为O(n)