1.题目
Given an array with n
integers, your task is to check if it could become non-decreasing by modifying at most 1
element.
We define an array is non-decreasing if array[i] <= array[i + 1]
holds for every i
(1 <= i < n).
Example 1:
Input: [4,2,3] Output: True Explanation: You could modify the first4
to1
to get a non-decreasing array.
Example 2:
Input: [4,2,1] Output: False Explanation: You can't get a non-decreasing array by modify at most one element.
Note: The n
belongs to [1, 10,000].
2.思路
这题真的是绕了我好久,越绕越乱。主要是没理明白思路。心态略微有点崩,稳定下来之后,终于有点理顺了。
总结来说,
1.假设突变点出现在中间段(非头、非尾),要求这个突变点前后两段数据都是非递减的。用两个变量,one记录未发生异常的最大数据,second记录未发生异常的第二大数据。i从 2 到 len-2 遍历数组中每一个元素nums[i],若监测到nums[i]<nums[i-1],即出现了突变点。则要么满足nums[i+1]>=one 要么满足nums[i]>=second,否则返回false;具体的可以画图感受一下。
(因为nums[i]<nums[i-1],则问题发生在i-1这个元素,和第i个元素二者之一。则要么 i 有问题,要么 i-1 有问题,所以有两种情况。)
2.对头来说,假如nums[0]>nums[1],则为头突发点;对尾来说,假如nums[len-1]<nums[len-2],则为尾突发点。
整个数组,突发点最多有1个,否则返回false。
3.算法
public boolean checkPossibility(int[] nums) {
int res=0;//记录突发点个数
int len = nums.length;//数组的长度,记录为len
if(len==0||len==1)return true;
int one;//目前最大的数
int second;//目前第二大的数
if(nums[0]>nums[1]){
one = nums[0];
second = nums[1];
res+=1;
}else{
one = nums[1];
second = nums[0];
}
if(len>2){
for(int i=2;i<len-1;i++){
if(nums[i]>=nums[i-1]){
if(nums[i]>one){
second=one;
one = nums[i];
}
}else{//数据发生异常的时候,不更新one和second值
if(nums[i]>=second||nums[i+1]>=one){
res+=1;
if(res>1)return false;
}
else return false;
}
}
if(nums[len-1]<nums[len-2]){
res+=1;
if(res>1)return false;
}
}
return true;
}
4.总结
啊真的被困扰好久,画图真的很重要。有的时候,空头想是想不清楚的。