调整数组为不降的序列

Posted new-start

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调整数组为不降的序列相关的知识,希望对你有一定的参考价值。

题目

You are given an array of integers in an arbitrary order. Return whether or not it is possible to make the array non-decreasing by modifying at most 1 element to any value.

We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).

Example:

[13, 4, 7] should return true, since we can modify 13 to any value 4 or less, to make it non-decreasing.

[13, 4, 1] however, should return false, since there is no way to modify just one element to make the array non-decreasing.
Can you find a solution in O(n) time?

分析

首先,很明显最多只能存在一对递减的数字。因为如果多于一对,则无论如何调整都不可能成功。
假设这2个数为 B, C.
现在只需要遍历一遍每个位置。对于每个位置的相邻数对 B, C 进行判断。如果 B > C:
那么同时需要考虑其前后2个数 A 和 D. 即取 A, B, C, D 这4个连续的数。有如下逻辑:
若 B <= D, 则可以通过增大 C 来成功调整 A, B, C, D 为不减的次序;
若 A <= C,则可以通过减小 B 来成功调整 A, B, C, D 为不减的次序;
另外需要考虑首尾两端的特殊情况,此时如果没有连续的4个数而只有3个数,则调整方式也会更自由。
其他情况,则肯定无法调整成功,直接返回 false.
否则,继续遍历其他位置,综合判断。

时间复杂度为 O(1).

代码

def check(lst):
    found_dec = False
    for i in range(0, len(lst) - 1):
        if lst[i] > lst[i+1]:
            if found_dec:
                return False # 出现了多于一对递减的数字对
            found_dec = True

            if i > 0 and lst[i-1] <= lst[i+1]:
                continue
            if i == 0 or i == len(lst) - 2:
                continue
            if i < len(lst) - 2 and lst[i] <= lst[i+2]:
                continue
            return False
        else:
            continue
    return True

print check([13, 4, 7])
# True
print check([5,1,3,2,5])
# False

以上是关于调整数组为不降的序列的主要内容,如果未能解决你的问题,请参考以下文章

最长不降子序列

最大不降子序列

bzoj 3289 : Mato的文件管理 (莫队+树状数组)

D1. Kirk and a Binary String (easy version)

翻转数组

翻转数组