https://leetcode-cn.com/problems/non-decreasing-array/
给你一个长度为 n 的整数数组,请你判断在 最多 改变 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
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。
说明:
1 <= n <= 10 ^ 4
- 10 ^ 5 <= nums[i] <= 10 ^ 5
- 数组
- 贪心
- 暂无
这道题简单就简单在它限定了在 最多 改变 1 个元素的情况下,如果不限定这个条件,让你求最少改变多少个数字,就有点难度了。
对于这道题来说,我们可以从左到右遍历数组 A, 如果 A[i] < A[i - 1],我们找到了一个递减对。遍历过程中的递减对个数大于 1,则可提前返回 False。
于是,大家可能写出如下代码:
class Solution:
def checkPossibility(self, A: List[int]) -> bool:
ans = 0
for i in range(1, len(A)):
if A[i] < A[i - 1]:
if ans == 1: return False
ans += 1
return True
上面代码是有问题的,问题在于类似 [3,4,2,3]
的测试用例会无法通过。问题在于递减对的计算方式有问题。
对于 [3,4,2,3]
来说,其递减对不仅仅有 (4,2)。其实应该还包括 (4,3)。 这提示我们在这个时候应该将 2 修改为不小于前一项的数,也就是 4,此时数组为 [3,4,4,3]
。这样后续判断就会多一个(4,3) 递减对。
而如果是 [3,4,3,3]
,在这个例子中应该将前一项修改为 3,即 [3,3,3,3],因为末尾数字越小,对形成递增序列越有利,这就是贪心的思想。代码上,我们没有必要修改前一项,而是假设 ta 已经被修改了即可。
大家可以继续找几个测试用例,发现一下问题的规律。比如我找的几个用例: [4,2,3] [4,2,1] [1,2,1,2] [1,1,1,] []
。这样就可以写代码了。
- 考虑各种边界情况,贪心改变数组的值
- 语言支持:Python3
Python3 Code:
class Solution(object):
def checkPossibility(self, A):
N = len(A)
count = 0
for i in range(1, N):
if A[i] < A[i - 1]:
count += 1
if count > 1:
return False
# [4,2,3] [4,2,1] [1,2,1,2] [1,1,1,] []
if i >= 2 and A[i] < A[i - 2]:
A[i] = A[i - 1]
return True
复杂度分析
令 n 为数组长度。
- 时间复杂度:$O(n)$
- 空间复杂度:$O(1)$
- 最长上升子序列
此题解由 力扣刷题插件 自动生成。
力扣的小伙伴可以关注我,这样就会第一时间收到我的动态啦~
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。