代码的目的是查看序列是否几乎要增加,也就是说,可以通过删除单个元素来严格增加序列。
例如:如果删除索引1处的元素,则[1、3、2、3]将严格增加。 [1、2、1、2]几乎没有增加,因为如果删除第一个'2',则得到的[1、1、2]不会严格增加。
我的代码必须在4000毫秒内工作,长度为2 <= len <= 10 ^ 5。它很可能会陷入很长的序列。
def almostIncreasingSequence(sequence):
length = len(sequence)
count = 0
for previous, next in zip(sequence[:-1],sequence[1:]):
if previous < next:
count +=1
if (length-count>2):
return False
return True
[1、2、1、2]
[1、2、3、4、5、3、5、6]
[40,50,60,10,20,30]
不起作用..请帮忙
请注意,这不是一个家庭作业问题,正如你们大多数人都知道的那样,在线发布了很多有关该问题的答案,我想知道我是否可以这样做
答案 0 :(得分:1)
对于我来说,最简单的事情是检查对并删除干扰序列的元素。在检查了i的相邻元素之后,我还检查了i的周围元素。如果通过删除i仍然有一个受干扰的序列,则我将i + 1删除,然后退后一步以再次开始检查。我已经在38个不同的测试用例上对此进行了测试。让我知道是否有任何错误。
def almostIncreasingSequence(sequence):
count = 0
i =0
size = len(sequence)
if(sequence[0]>sequence[1]): #separate case for the first element
sequence.pop(0)
count+=1 #update the count everytime I remove an element
size-=1 # I change the size everytime i remove an element
while(i<size-1):
if sequence[i]>=sequence[i+1]:
count+=1
if(sequence[i+1]<=sequence[i-1]):
sequence.pop(i+1)
else:
sequence.pop(i)
size = len(sequence)
if i>0:
i-=1
else:
i+=1
if count>1:
return False
else:
return True
答案 1 :(得分:0)
这有效:
import timeit
import random
def increasing_sequence_pos(sequence):
for n, (a, b) in enumerate(zip(sequence[:-1], sequence[1:])):
if a >= b:
return False, n + 1
return True, -1
def almost_increasing_sequence(sequence):
increasing, n = increasing_sequence_pos(sequence)
return (
# either it was already increasing
increasing or
# or the problem is with the last element
n == len(sequence)-1 or
((
# or the element at position n was the problem
(sequence[n - 1] < sequence[n + 1]) or
# or the element at position n-1 was the problem
(sequence[n - 2] < sequence[n] < sequence[n + 1])
) and increasing_sequence_pos(sequence[n + 1:])[0])
)
size = 1000000
# time on simple increasing series
numbers = list(range(size))
print(timeit.timeit(lambda: almost_increasing_sequence(numbers), number=1))
print(f'Result: {almost_increasing_sequence(numbers)}')
# time on single issue
numbers[random.randint(1, size)] = 0
print(timeit.timeit(lambda: almost_increasing_sequence(numbers), number=1))
print(f'Result: {almost_increasing_sequence(numbers)}')
# time on two issues issue
numbers[random.randint(1, size)] = 0
print(timeit.timeit(lambda: almost_increasing_sequence(numbers), number=1))
print(f'Result: {almost_increasing_sequence(numbers)}')
请注意您如何获得不同的时间,时间当然取决于执行的硬件,因此“ 4000ms”相当愚蠢(即使使用非常非常糟糕的代码,也很容易在现代计算机上实现)。
您会注意到,第一个比较稳定(在我的工作站上为0.07秒),而第二个和第三个通常要短很多,甚至要短一些。
示例输出:
0.07000060000000001
Result: True
0.06909959999999998
Result: True
0.06430069999999999
Result: False
请注意,递增的序列也被视为几乎递增的序列。
答案 2 :(得分:0)
def seqIncCheck(lst):
temp = lst[0]
for i in range(1,len(lst)):
if lst[i] > temp:
temp = lst[i]
continue
else:
return False
return True
答案 3 :(得分:0)
您的算法甚至不正确。您只是在检查是否有一个或小于前一个元素的元素。但是,这并不意味着它是一个“几乎增加”的序列。
简而言之,当遇到一个小于其前一个元素的元素时,如果通过删除该元素本身或通过删除前一个元素来“严格增加”该序列,则该序列将“几乎增加”。
例如
1, 2, 3, [2*], 4, 5, 6
1, 2, 3, 100*, [4], 5, 6
1, 2, 3, [1], 2, 3
在前2个示例中,[]
中的数字是小于前一个的元素。但是,带有*
的数字是需要删除的数字以形成严格递增的序列。第三个示例是一个仅包含一个比以前小的元素的示例,但这并不是一个几乎递增的序列
所以最简单的逻辑(用伪代码)类似于:
def is_almost_increasing(seq):
for i in 1 to len(seq):
if seq[i] <= seq[i-1]:
return ( is_strictly_increasing(seq[:i-1] + seq[i:]
or is_strictly_increasing(seq[:i] + seq[i+1:] )
return true
(is_strictly_increasing is simple, will just leave it to you)
有一些技巧可以使速度更快(例如,您实际上不需要重新检查已经确认增加的部分),但这对您来说是个不错的起点。
答案 4 :(得分:0)
好吧,我想出的方法是使用另一个与错误条件匹配的忽略索引数组,这样循环就不会使用这些索引,并且如果条件匹配不止一次,则它几乎不会增加序列。 在这里,我使用了 ignoreindex 列表并添加了与条件匹配的索引。循环将使用列表忽略索引号,这样它就不会两次检查相同的数字。我试图通过从列表本身中删除元素来简单地做到这一点,但不知何故`def几乎IncreasingSequence(序列):
count = 0
ignoreindex = []
for i in range(0,len(sequence)-1):
for j in range(i+1,len(sequence)):
if i not in ignoreindex:
if j not in ignoreindex:
print("The index are %d,%d"%(i,j))
if sequence[j] <= sequence[i]:
print(i,j)
count += 1
print(count)
# if the same number are at two different location ignore the later index
if sequence[j] == sequence[i] and j - i > 1:
ignoreindex.append(j)
# else ignore the earlier index
else:
ignoreindex.append(i)
print(sequence)
print(ignoreindex)
if count > 1:
return False
return True`