获取严格递增序列python

问题描述 投票:0回答:6

问题:

“给定一个整数序列作为数组,确定是否可以通过从数组中删除不超过一个元素来获得严格递增序列。

注意:序列 a0, a1, ..., an 被认为是严格递增的 if a0 < a1 < ... < an. Sequence containing only one element is also considered to be strictly increasing.

示例:

  • 对于序列 = [1, 3, 2, 1],输出应该是 解决方案(序列)= false。为了获得严格递增的序列,该数组中没有任何一个元素可以被删除。

  • 对于序列 = [1, 3, 2],输出应该是 解决方案(序列)= true。您可以从数组中删除 3 以获得严格递增的序列 [1, 2]。或者,您可以删除 2 以获得严格递增序列 [1, 3]。”

这是我的代码:

def solution(sequence):
    if len(sequence) == 1:
        return True
    else:
        count = 0
        for i in range(0,len(sequence) - 1):
            if sequence[i] >= sequence[i + 1]:
                count = count + 1
        for i in range(0,len(sequence) - 2):
            if sequence[i] >= sequence[i + 2]:
                count = count + 1
    return count <= 1

我的代码涵盖三种情况:

情况 1:当序列只有一个元素长时。我在第一个 if 语句中发现了这一点。

情况 2:如果有多个下步(邻居小于所考虑的元素的情况),则无法仅通过一次删除来调整序列,因此我们得到 false(计数 > 1) 。我在第一个 if 语句中发现了这一点。

情况3:然而,在某些情况下,只有一个下步,但仍然没有办法只删除一个元素。当第二个元素也小于所考虑的元素时,就会发生这种情况。例如,对于 [1,4,3,2],即使你删除了 3,你仍然会得到一个下台阶。现在,我通过进行第二次检查来覆盖这种情况,该检查检查元素二是否较少,如果是,则我们添加到计数中。

案例4:有一种情况我的代码没有涵盖,这似乎是唯一的一种,那就是当一个元素的邻居和下一个元素都小于所考虑的元素时,但我们可以解决这个问题只需删除正在考虑的元素即可。因此,对于 [1,4,2,3],2 和 3 都小于 4,但如果我们去掉 4,那就很好了。当问题元素是序列中的第一个元素或不是序列中的第一个元素时,这种情况都可能发生。我不知道如何正确捕捉这一点。我想你可能会添加一个条件来查看 i-2 是否小于 i+1,但是当 i 索引第一个元素时这将不起作用,而且非常麻烦。我不知道如何解决这个问题。

我很确定我把事情变得过于复杂了,真正需要的是退后一步,想出一个不那么零散的解决方案,但我被困住了。有人可以帮忙吗?请注意,我们不必实际获得严格递增的序列;我们只需要看看是否可以。

python arrays sequence
6个回答
1
投票

这是一个你可以看看的想法(评论后编辑)

def distinct(L: list[int]) -> bool:
    return len(L) == len(set(L))

def almost_increasing(L: list[int]) -> bool:

    # some trivial cases
    if len(L) <= 2:                                   return True
    if L[1: ] == sorted(L[1: ]) and distinct(L[1: ]): return True
    if L[:-1] == sorted(L[:-1]) and distinct(L[:-1]): return True
    
    return any(
        L[  :i] == sorted(L[  :i]) and distinct(L[  :i]) and
        L[i+1:] == sorted(L[i+1:]) and distinct(L[i+1:]) and
        L[i-1 ] < L[i+1]
        for i in range(1, len(L)-1)
    )

这是一个很好的方法,您可以使用 hypothesispytest 来测试它:

@given(L=st.lists(st.integers(), min_size=2, max_size=6))
def test_almost_increasing(L: list[int]):

    expected = False
    for i in range(len(L)):
        Lcopy = L.copy()
        del Lcopy[i]
        expected |= (Lcopy == sorted(Lcopy) and distinct(Lcopy))
    
    received = almost_increasing(L)
    assert received == expected

1
投票

让我们将输入分成最多两个递增的子序列。如果这是不可能的,则返回 false。

如果只有一个序列,则返回true。

如果任一序列的长度为 1,则答案为 true - 我们只需删除该元素即可。

否则,我们可以通过删除第一个序列中的最后一项或第二个序列中的第一项来连接两个序列。也就是说,

 if a[j-2] < a[j]     -> ok, remove a[j - 1]
 if a[j-1] < a[j + 1] -> ok, remove a[j]

其中

j
是第二个序列开始的索引。

代码:

def check(a):
    j = 0

    for i in range(1, len(a)):
        if a[i - 1] >= a[i]:
            if j > 0:
                return None
            j = i

    if j == 0:
        return a

    if j == 1:
        return a[1:]

    if j == len(a) - 1:
        return a[:-1]

    if a[j - 2] < a[j]:
        return a[:(j - 1)] + a[j:]

    if a[j - 1] < a[j + 1]:
        return a[:j] + a[(j + 1):]

    return None


assert check([2, 4, 6, 8]) == [2, 4, 6, 8], 'j == 0'
assert check([9, 4, 6, 8]) == [4, 6, 8], 'j == 1'
assert check([4, 6, 8, 1]) == [4, 6, 8], 'j == len-1'
assert check([2, 4, 9, 6, 8]) == [2, 4, 6, 8], 'j-2 < j'
assert check([2, 4, 1, 6, 8]) == [2, 4, 6, 8], 'j-1 < j+1'

assert check([2, 2, 2, 2]) is None, 'early return'
assert check([2, 8, 9, 6, 1]) is None, 'early return'

assert check([2, 4, 9, 3, 5]) is None, 'last return'

assert check([2]) == [2]

1
投票

试试这个

def solution(sequence):
    n = len(sequence)
    for i in range(n):
        count = 0
        trail = sequence[:]
        del trail[i]
        m = len(trail)
        for j in range(m-1):
            if trail[j] >= trail[j+1]:
                count += 1
        if count == 0:
            return True
    return False

这既不高效也不优化,但它确实有效。


0
投票

试试这个:

def is_solution(list_to_check):
    if len(list_to_check) == 1:
        return True
    for i in range(1, len(list_to_check)):
        if list_to_check[i] <= list_to_check[i - 1]:
            new_list = list_to_check[:i - 1] + list_to_check[i:]
            if (list_to_check[i] > list_to_check[i - 2]
                and new_list == sorted(new_list)):
                return True
            elif (i == len(list_to_check) - 1
                  and list_to_check[:-1] == sorted(list_to_check[:-1])):
                return True
    return False


if __name__ == '__main__':
    list_to_check = [1, 2, 1]
    print(is_solution(list_to_check))

0
投票
def solution(sequence):
boolean_list = []
setted = set(sequence)
#this if checks for 2 or more duplicated numbers
if (len(sequence) - len(setted)) >= 2:
    return False
else:
    #this for loop runs for every i item in sequence list
    for i in sequence:
        test = []
        #this for loop creates a test list without i item
        for j in sequence:               
            if j != i:
                test.append(j)
        # this variable checks if all the items in the test list are in ascending order
        is_ascending = all(test[x] <= test[x+1] for x in range(len(test)-1))
        # this is a list of boolean values with the result of every case
        boolean_list.append(is_ascending)
    # this returns True if at least one case is True else it returns False
    return any(boolean_list)

-1
投票
def solution(sequence):
    """determine strict increase"""
    sequence_length = len(sequence)
    if (
        sequence_length == 0
        or not len(set(sequence)) + 1 >= sequence_length
    ):
        return False
    return True
© www.soinside.com 2019 - 2024. All rights reserved.