665. 非递减数列

246 阅读1分钟

题目描述

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

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

示例

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

来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/no…

实现

/*
 * nums[i]>nums[i+1]时,查看nums[i-1],如果nums[i-1]<=nums[i+1]的话可以让nums[i]和nums[i-1]相等,如3,2,4,可以换成3,4,4,就符合要求
 * 如果nums[i-1]>nums[i+1],那么让nums[i+1]=nums[i],nums[i]前面一定判断过大于nums[i-1]了,如3,4,1,可以换成3,4,4,符合要求
 * 因此有两种修改情况 1. 将nums[i]缩减至nums[i+1] 2. 将nums[i + 1]放大至nums[i]
 * 参考解答:https://leetcode-cn.com/problems/non-decreasing-array/solution/xue-shi-yao-suan-fa-xue-xiu-lu-by-magica-u8fc/
 */
bool checkPossibility(int *nums, int numsSize)
{
    if (numsSize <= 1 || nums == NULL) {
        return true;
    }
    int flag = 0;    // 标记改变元素的次数,超过1次就不符合了

    // 查看头元素
    if (nums[0] > nums[1]) {    // nums[0]>nums[1]时,nums[0]可以无限小(没有左边界),因此可以直接改变为符合的情况
        flag = 1;
    }

    for (int i = 1; i < numsSize - 1; i++) {
        if (nums[i] > nums[i+1]) {
            if (flag >= 1) {    // 已经替换过了,不能再替换
                return false;
            }
            if (nums[i+1] >= nums[i-1]) {
                nums[i] = nums[i+1];
            } else {
                nums[i+1] = nums[i];
            }
            flag++;
        }
    }
    return true;
}