··https://leetcode-cn.com/problems/non-decreasing-array/
根据题意,破坏非递减数组序列的结构是‘N’字型结构。具体解法可以设置双指针,分别从数组两端往中间搜索,当碰到失序地方的时候停下来。如下图所示:
image.png
若至多改变一个元素能将原数组调整有序,当只有一处失序存在时必定有high = low + 1,当数组完全符合非递减时high = low,因此high-low<=1是命题的必要条件。
另一方面如图所示,当失序的时候有两种调整方案:
1.改变位置low,使得nums[low-1]≤nums[low]≤nums[low+1];
2.改变位置high,使得nums[high-1]≤nums[high]≤nums[high+1];
采用方案1前提条件为nums[low+1]>=nums[low-1],采用方案2前提条件为nums[high+1]>=nums[high-1]。
再考虑两种端点情况,即在最开始和最结尾失序,low=0或者high=len-1时,一定可以调整。最终代码如下:
public static boolean checkPossibility(int[] nums) {
int len = nums.length;
if(len<=2) return true;
int low=0,high = nums.length-1;
while (low<high&&nums[low]<=nums[low+1])low++;
while (low<high&&nums[high]>=nums[high-1])high--;
return high-low<=1 && (low == 0||high==len-1||nums[high+1]>=nums[high-1]||nums[low+1]>=nums[low-1]);
}