Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most1 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 first 4 to 1 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].
Solutions
My solution
Idea: nums[0..i] and nums[j..n-1] are longest non-decreasing sequences starting at nums[0] and ending at nums[n-1], respectively.
classSolution {public:boolcheckPossibility(vector<int>& nums) {int i =0, n =nums.size();while(i +1< n &&nums[i] <=nums[i +1]) ++i; // i == n - 1, the whole array is non-decreasing // i == n - 2, we can change the last element to make the array non-decreasing.if(i >= n -2) returntrue;int j = n -1; // no need to check j > 0 because // nums[i] > nums[i + 1] // so the while loop must terminatewhile(nums[j -1] <=nums[j]) --j; // if j - i > 1, at least two reverse pairs // i.e., (nums[i], nums[i + 1]) and (nums[j - 1], nums[j])if(j - i >1) returnfalse; // i + 1 == j // only one reverse pair // check if it's possible to change either nums[i] or nums[j] // to make the array non-decreasingreturn i ==0||nums[i -1] <=nums[j] ||nums[i] <=nums[j +1]; }};
Solution 1
Explanation: if there is a reverse pair (nums[i], nums[i + 1]). We need to change either nums[i] or nums[i + 1]. If i > 0 && nums[i - 1] > nums[i + 1], we must change nums[i + 1]. Otherwise, we can change either nums[i] or nums[i + 1]. But we prefer changing nums[i] because if we can change nums[i + 1] (i.e., let nums[i + 1] = nums[i]) to make the array non-decreasing, then we can also change nums[i] (i.e., let nums[i] = nums[i + 1]) to make the array non-decreasing (the other direction is not true).
classSolution {public:boolcheckPossibility(vector<int>& nums) {int count =0; // we can use some variable to remember the modified element // if we don't want the array to be changed when the function returns. //int idx = -1, val = -1;for(int i =0; i +1<nums.size(); ++i){if(nums[i] >nums[i +1]){if(++count >1)returnfalse; // if i == 0 || nums[i - 1] <= nums[i + 1], we can change nums[i] to nums[i + 1] // otherwise, we have to change nums[i + 1] to nums[i]if(i >0&&nums[i -1] >nums[i +1]){ //idx = i + 1; //val = nums[i + 1];nums[i +1] =nums[i]; } } } //if(idx != -1) nums[idx] = val;returntrue; }};