持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
前言
我发现一般越是简短的题目越容易做错,总是少考虑情况,今天来一道中等难度的数组相关的题目,先看题目吧
题目描述
给你一个长度为 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
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。
解题思路
这一题的关键点在于以下几点:
- 首先是只能更改一个数字来达到非递减减数列,这时候假设遇到了一个数组是[2,4,3],这时只要把4改为3就满足条件了
- 还有一种情况是,加入遇到了一个数组是[3,6,1],这时候如果按上边的方法来处理就会变成[3,1,1],这就不符合要求了,但如果改变成[3,6,6]就是符合要求的,所以当发现前一项大于后一项时要分为两种情况来处理
- 还需要设置一个count,用来标记已经进行了几次更改,如果大于0直接返回false即可 代码如下:
/**
* @param {number[]} nums
* @return {boolean}
*/
var checkPossibility = function (nums) {
let count = 0
let midValue = 0 //用来记录改变值之前的nums[i]
for (let i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
if (count > 0) {
return false
} else {
midValue = nums[i]
nums[i] = nums[i + 1] //这里就是第一种处理方式,当遇到前一项大于后一项的时候,直接把当前项改为后一项的值
//这里要特别注意,上述的赋值操作可能引出第二种情况,也就是思路中说的第二点,改变的值可能又小于了前一项,所以要做特殊处理
if (nums[i] < (i - 1 >= 0 ? nums[i - 1] : 0)) {
nums[i + 1] = midValue
nums[i] = midValue
if (!count) {
count++
} else {
return false
}
continue
} else {
if (!count) {
count++
} else {
return false
}
}
}
}
}
return true
};
运行结果如下图:
总结
做之前总情况考虑不全,妥妥的面向测试数据编程,啥时候才能做题之前把情况都考虑清楚啊,唉