665 non-decreasing array

  • 题目要求
    给定一个数组,判断能否通过修改 最多 一个元素,使该数组成为一个非递减序列
  • 解题过程
    • 一开始的思路是判断序列中递减序列对的个数,如果超过2个,说明没法只修改一个元素使其变为非递减序列。

然而这种方法并没有考虑到一种情况:仅存在一对递减序列,该递减序列在两个非递减序列之间,或者在序列首尾。如:3412,423,-1423

  • 既然第一种思路没有检验出修改之后的序列,那我的想法是对序列进行修改,检测修改之后的序列。

然而又出现了新的状况,出现了递减序列,应该修改哪个元素呢?即a[i] = a[i+1] or a[i+1] = a[i]
修改前一个元素? 可能会破坏前面序列的增减性,凭空产生了新的递减序列。
修改后一个元素?也有反例:423, 可能会破坏后面序列的增减性,产生新的递减序列。

正确思路;
1.(暴力搜索)
对于序列中所有元素,我们都将他赋值为前一个元素,然后测试有没有递减序列。
若有,说明这次赋值是错误的,需要回溯,然后转向下一个元素。
若没有,可以直接返回true。
将所有元素全部完成赋值尝试之后,如果仍然没有返回true,说明无法通过只修改一个元素使序列费递减,那我们返回false。
时间复杂度O(n^2)

2.(化简后暴力搜)
对于序列中递减序列的检测,我们可以把针对整个序列的问题转化为局部问题。
检查序列首尾元素,若他们是非递减的,删去边缘元素(首删首,尾删尾),最终得到化简序列。
如果序列长度:
小于等于2,说明可以
大于等于5,说明不可以
(大于5肯定不可以,
等于5:
a3 如果我们调整a3(只能更大),a5肯定比a3小;
如果我们调整a5,a3小于a1或a2)
3或4,进行暴力搜索

由于最多进行4次循环来暴力搜索,大部分时间用在遍历首尾序列,时间复杂度为O(n)

其实只要在一开始的思路的基础上对于递减序列的位置分类讨论即可。
在首部或尾部,首改首,尾改尾,返回true
在中间,既可以尝试修改a[i],也可以尝试修改a[i+1],使得a[i-1]<=a[i]<=a[i+1]<=a[i+2]
要修改a[i],必须满足a[i-1]<=a[i+1],
要修改a[i+1],必须满足a[i]<=a[i+2]
(如果一种不行,可以尝试第二种,两种都不行,说明没法只修改一个元素使得序列非递减),

你可能感兴趣的:(665 non-decreasing array)