非递减数列

简介: 非递减数列

非递减数列(算法题)

题目:给你一个长度为 n 的整数数组 nums ,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。

我们是这样定义一个非递减数列的: 对于数组中任意的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。

示例1:

输入: nums = [4,2,3]
输出: true
解释: 你可以通过把第一个 4 变成 1 来使得它成为一个非递减数列。

示例2:

输入: nums = [4,2,1]
输出: false
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。

提示:

  • n == nums.length
  • 1 <= n <= 104
  • -105 <= nums[i] <= 105

思路

假设有两个不同的下标 i, j满足上述不等式,不妨设 i<j。

若 i+1<j,则无论怎么修改 nums[i]或nums[i+1],都不会影响 nums[j]与 nums[j+1]之间的大小关系;修改 nums[j] 或nums[j+1] 也同理。因此,这种情况下,我们无法将nums 变成非递减数列。

若i+1=j,则有 nums[i]>nums[i+1]>nums[i+2]。同样地,无论怎么修改其中一个数,都无法使这三个数变为 nums[i]≤nums[i+1]≤nums[i+2] 的大小关系。

因此,上述问题的结论是:

至多一个。

满足这个条件就足够了吗?并不,对于满足该条件的数组 3,4,1,2[3,4,1,2] 而言,无论怎么修改也无法将其变成非递减数列。

因此,若找到了一个满足 nums[i]>nums[i+1]的 i,在修改 nums[i]或 nums[i+1]之后,还需要检查 nums 是否变成了非递减数列。

我们可以将 nums[i] 修改成小于或等于 nums[i+1]的数,但由于还需要保证 nums[i]不小于它之前的数,nums[i]越大越好,所以将 nums[i]修改成 nums[i+1] 是最佳的;同理,对于 nums[i+1],修改成 nums[i] 是最佳的。

class Solution {
public:
    bool checkPossibility(vector<int> &nums) {
        int n = nums.size();
        for (int i = 0; i < n - 1; ++i) {
            int x = nums[i], y = nums[i + 1];
            if (x > y) {
                nums[i] = y;
                if (is_sorted(nums.begin(), nums.end())) {
                    return true;
                }
                nums[i] = x; // 复原
                nums[i + 1] = x;
                return is_sorted(nums.begin(), nums.end());
            }
        }
        return true;
    }
};
相关文章
|
4月前
|
C++
给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
|
5月前
27.数列1,2,2,3,3,3,4,4,4,4,5,……
27.数列1,2,2,3,3,3,4,4,4,4,5,……
43 0
LeetCode-334 递增的三元子序列
LeetCode-334 递增的三元子序列
|
5月前
leetcode-334:递增的三元子序列
leetcode-334:递增的三元子序列
31 0
|
算法
斐波那切数列
斐波那切数列
105 0