665. Non-decreasing Array*

探讨LeetCode 665题:通过最多修改一次元素判断数组是否能变为非递减。文章分析了两种解题思路,分别是在修改输入数组和不修改输入数组的情况下的解决方案,并提供了详细的C++代码实现。

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值