题目序号:
665
题目 :
给定一个长度为 n 的整数数组,你的任务是判断在最多改变 1 个元素的情况下,该数组能否变成一个非递减数列。
分析:
已知最终得到的数据每一项一定大于等于前一项,即:
n
u
m
s
[
i
−
1
]
<
=
n
u
m
s
[
i
]
<
=
n
u
m
s
[
i
+
1
]
,
0
<
i
<
l
e
n
(
n
u
m
s
)
−
1
nums[i-1]<=nums[i]<=nums[i+1],0<i<len(nums)-1
nums[i−1]<=nums[i]<=nums[i+1],0<i<len(nums)−1
所有我们需要把数组中的每一个相邻的三个数满足这样的条件:
然而不符合的相邻三个数共有这样的三种形式:
- n u m s [ i − 1 ] < n u m s [ i + 1 ] < n u m s [ i ] nums[i-1]<nums[i+1]<nums[i] nums[i−1]<nums[i+1]<nums[i]
- n u m s [ i + 1 ] < n u m s [ i − 1 ] < n u m s [ i ] nums[i+1]<nums[i-1]<nums[i] nums[i+1]<nums[i−1]<nums[i]
- n u m s [ i + 1 ] = n u m s [ i − 1 ] < n u m s [ i ] nums[i+1]=nums[i-1]<nums[i] nums[i+1]=nums[i−1]<nums[i]
为了方便所示,我们用图来表示:
为了得到非递减数列,我们需要对每组相邻三数进行改变,这里我们保证不对后面数据改变的前提下,对其进行局部最优的改变。
- n u m s [ i ] = n u m s [ i + 1 ] nums[i] = nums[i+1] nums[i]=nums[i+1]
- n u m s [ i + 1 ] = n u m s [ i ] nums[i+1] = nums[i] nums[i+1]=nums[i]
- n u m s [ i ] = n u m s [ i + 1 ] ( n u m s [ i − 1 ] ) nums[i] = nums[i+1](nums[i-1]) nums[i]=nums[i+1](nums[i−1])
改变后如图所示:
ps:这里我们这里我们可以将1,3情况合并。
我们可以发现,每个三元数组只会改变第二个和第三个数据,所以我们只需要在数列的开头补一个小于等与数组第一个数的数字即可。
题目要求这样的有效操作最多为1次,所以对有效操作计数即可。
代码部分
class Solution:
def checkPossibility(self, nums: List[int]) -> bool:
cnt = 0
nums.insert(0,num[0])
for i in range(1, len(nums)-1):
if nums[i]>=nums[i-1] and nums[i]>nums[i+1] :
if nums[i+1]>= nums[i-1]:
nums[i] = nums[i+1]
else:
nums[i+1] = nums[i]
cnt+=1
if cnt>1:
return False
if cnt <= 1:
return True