665. Non-decreasing Array*

​https://leetcode.com/problems/non-decreasing-array/description/​

题目描述

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 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]​​.

解题思路

参考:

思路 1: 虑 ​​a[i - 2]​​​, ​​a[i - 1]​​​ 以及 ​​a[i]​​​ 三个值的相对大小; 当遇到 ​​a[i - 1] > a[i]​​ 的时候, 需要考虑两种情况:

​a[i - 2]​​​ 不存在或者 ​​a[i - 2] <= a[i]​​​, 那么这个时候只需要减小 ​​a[i-1]​​​ 的值(比如说让 ​​a[i - 1] = a[i]​​​, 另一方面, 如果选择增大 ​​a[i]​​​ 的值, 风险在于 ​​a[i+1]​​​ 可能就不能满足 ​​a[i+1]>=a[i]​​​ 了, 因此, 优先选择减小 ​​a[i-1]​​​ 的值)就行;
​​​a[i - 2] > a[i]​​​, 这个时候, 就只能增大 ​​a[i]​​​ 的值了.
不管哪种情况, 都需要使用 ​​​modified​​​ 来统计修改的次数, 如果修改的次数大于 ​​1​​​, 那么就返回 ​​false​​​; 否则返回 ​​true​​.

C++ 实现 1

class Solution {
public:
bool checkPossibility(vector<int>& a) {
int modified = 0;
for (int i = 1; i < a.size(); i++) {
if (a[i] < a[i - 1]) {
if (modified++ > 0) return false;
if (i - 2 < 0 || a[i - 2] <= a[i]) a[i - 1] = a[i]; // lower a[i - 1]
else a[i] = a[i - 1]; // rise a[i]
}
}
return true;
}
};

C++ 实现 2

思路 2:(不修改原数组) 从思路一中可以看到, 策略是:

在 ​​a[i - 1] > a[i]​​ 的情况下:

  • ​a[i - 2] <= a[i]​​​, lower​​a[i - 1]​​;
  • ​a[i - 2] > a[i]​​​, raise​​a[i]​​​;
    为了不修改原数组, 需要使用变量​​​prev​​​ 来保存​​a[i-1]​​​ 的值, 只有在​​a[i - 2] > a[i]​​​ 的情况下, 才不需要修改​​prev​​​ 的值(此时的策略是提升​​a[i]​​​, 注意​​modified​​ 此时也增加了).
class Solution {
public:
bool checkPossibility(vector<int>& a) {
int modified = 0;
int prev = a[0];
for (int i = 1; i < a.size(); i++) {
if (a[i] < prev) {
if (modified++ > 0) return false;
if (i - 2 >= 0 && a[i - 2] > a[i]) continue;
}
prev = a[i];
}
return true;
}
};