[英]Creating a strictly increasing sequence minus 1 element
I am working through a code challenge where I am to check if a list is strictly increasing if I remove no more than 1 element from the list.我正在处理一个代码挑战,如果我从列表中删除不超过 1 个元素,我将检查列表是否严格增加。 Here are some input/output examples:以下是一些输入/输出示例:
For sequence = [1, 3, 2, 1], the output should be
almostIncreasingSequence(sequence) = false.
There is no one element in this array that can be removed in order to get a strictly increasing sequence.
For sequence = [1, 3, 2], the output should be
almostIncreasingSequence(sequence) = true.
This is the logic I've built.这是我建立的逻辑。 Basically, I've created a copy of list and I'm doing the testing on the copy.基本上,我已经创建了一个列表副本,并且正在对副本进行测试。 I remove one element in each iteration and if it is strictly increasing, I increment the counter by a value of 1 but if it isn't, I decrement it by one.我在每次迭代中删除一个元素,如果它严格增加,我将计数器增加 1,但如果不是,我将其减少 1。 At the end, I check if the counter is greater than or equal to 0 and return a boolean value based on that:最后,我检查计数器是否大于或等于 0,并基于此返回 boolean 值:
def almostIncreasingSequence(sequence):
check = 0
sequence_copy = sequence
for element in sequence:
sequence_copy.remove(element)
if all(i < j for i, j in zip(sequence_copy, sequence_copy[1:])):
check += 1
else:
check -= 1
sequence_copy = sequence
if check > 0:
return True
else:
return False
However, there are 2 issues with this code.但是,此代码存在 2 个问题。 First of all, the logic does not work on some test cases like this one:首先,逻辑不适用于像这样的一些测试用例:
Input: sequence: [1, 3, 2]
Output: false
Expected Output: true
And the other issue is that the code takes too long for larger sequences.另一个问题是代码对于更大的序列来说花费的时间太长。 How can I fix my existing code to make it faster and generic for every kind of input?如何修复现有代码以使其对每种输入都更快、更通用? While I appreciate all help, just posting an answer does not help me at all since this is a code challenge meant for learning.尽管我感谢所有帮助,但仅发布答案对我毫无帮助,因为这是一个旨在学习的代码挑战。 Telling me how to optimize my code helps far more than just an answer.告诉我如何优化我的代码不仅仅是一个答案。
From the start, find the strictly increasing prefix.从一开始,找到严格递增的前缀。 From the end find the strictly increasing suffix (strictly decreasing from the end).从末尾找到严格递增的后缀(从末尾严格递减)。
If they overlap, return true because the whole sequence is strictly increasing.如果它们重叠,则返回 true,因为整个序列是严格递增的。
If there are any elements between them, then return false.如果它们之间有任何元素,则返回false。
Otherwise, the prefix and suffix are adjacent.否则,前缀和后缀是相邻的。 Return true if you can connect them into an increasing sequence by deleting the last element in the prefix, or the first element in the suffix.如果您可以通过删除前缀中的最后一个元素或后缀中的第一个元素将它们连接成递增序列,则返回 true。
Try to reduce the number of times you perform an operation that requires you to iterate over the array.尝试减少执行需要遍历数组的操作的次数。 Here's one way where you only need one loop through the array.这是一种只需要一个循环遍历数组的方法。
def isStrictlyIncreasing(sequence):
for elem1, elem2 in zip(sequence[:-1], sequence[1:]):
if elem1 >= elem2:
return False
return True
def almostIncreasingSequence(sequence):
seq_copy1 = sequence[:]
seq_copy2 = sequence[:]
for i, (elem1, elem2) in enumerate(zip(sequence[:-1], sequence[1:])):
if elem1 >= elem2:
seq_copy1.pop(i)
seq_copy2.pop(i+1)
return isStrictlyIncreasing(seq_copy1) or isStrictlyIncreasing(seq_copy2)
return True
Explanation:解释:
isStrictlyIncreasing() checks that a sequence is strictly increasing. isStrictlyIncreasing() 检查序列是否严格递增。 Pretty self explanatory很不言自明
almostIncreasingSequence() makes two copies of the sequence.几乎IncreasingSequence() 制作序列的两个副本。
True
.如果我们到达 function 的末尾,我们从来没有找到一个不增加的对,所以列表是严格增加的,所以返回True
。To solve this problem in linear time
we have to first pre-process the given array.为了linear time
解决这个问题,我们必须首先预处理给定的数组。
Suppose the array is [1,2,3,4,5,2,6,7]
, now we will make two additional arrays.假设数组是[1,2,3,4,5,2,6,7]
,现在我们将制作两个额外的 arrays。
increasingPrefix
which will be a boolean array, in this array i-th
element is True
iff the prefix till i
is an strictly increasing sequence. increasingPrefix
前缀,它将是一个 boolean 数组,在这个数组i-th
元素为True
,如果prefix till i
是严格递增的序列。
Similarly, we will make another array increasingSuffix
which will also be a boolean array, here i-th
element is True
iff suffix till i
is a strictly increasing sequence.同样,我们将创建另一个数组increasingSuffix
,它也将是一个boolean数组,这里i-th
元素是True
,如果suffix till i
是严格递增的序列。
So所以
array = [1, 2, 3, 4, 5, 2, 6, 7]
increasingPrefix = [True, True, True, True, True, False, False, False]
increasingSuffix = [False, False, False, False, False, True, True, True]
Now to check if the given array can become strictly increasing by removing no more than 1 element,现在检查给定数组是否可以通过删除不超过 1 个元素来严格增加,
we can simply traverse the given array and for each i-th
element we will check if我们可以简单地遍历给定的数组,对于每个i-th
元素,我们将检查是否increasingPrefix[i-1]==True and increasingSuffix[i+1]==True and array[i+1]>array[i-1]
. increasingPrefix[i-1]==True and increasingSuffix[i+1]==True and array[i+1]>array[i-1]
。
If above condition holds True
in any i-th
element than ans is True because we can remove i-th
element and the remaining array will be strictly increasing.如果上述条件在任何i-th
元素中为真,则 ans 为True
,因为我们可以删除i-th
元素,剩余的数组将严格增加。
Code for the above idea上述想法的代码
def fun(arr):
n=len(arr)
# empty and 1 length sequences are strictly increasing
if n<=1:
return True
increasingPrefix=[False]*n
increasingSuffix=[False]*n
increasingPrefix[0]=True
increasingSuffix[n-1]=True
# Calculate increasingPrefix values as described above
for i in range(1,n):
if arr[i]>arr[i-1]:
increasingPrefix[i]=True
else:
for j in range(i,n):
increasingPrefix[j]=False
break
# calculated increasingSuffix values as described above
for i in range(n-2,-1,-1):
if arr[i]<arr[i+1]:
increasingSuffix[i]=True
else:
for j in range(i,-1,-1):
increasingSuffix[j]=False
break
# traverse the given array and check for the conditions
ans=False
for i in range(n):
if i==0:
if increasingSuffix[i+1]:
ans=True
break
elif i==n-1:
if increasingPrefix[i-1]:
ans=True
break
else:
if increasingPrefix[i-1] and increasingSuffix[i+1] and arr[i+1]>arr[i-1]:
ans=True
break
return ans
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.