Python 求解几乎递增的序列(代码战)
给定一个整数序列作为数组,确定是否可以通过从数组中删除不超过一个元素来获得严格递增序列 范例 对于序列Python 求解几乎递增的序列(代码战),python,arrays,Python,Arrays,给定一个整数序列作为数组,确定是否可以通过从数组中删除不超过一个元素来获得严格递增序列 范例 对于序列[1,3,2,1],输出应为: almostIncreasingSequence(sequence) = false; almostIncreasingSequence(sequence) = true. 这个数组中没有一个元素可以被移除,以获得严格递增的序列 def almostIncreasingSequence(sequence): def is_increasing(lst
[1,3,2,1]
,输出应为:
almostIncreasingSequence(sequence) = false;
almostIncreasingSequence(sequence) = true.
这个数组中没有一个元素可以被移除,以获得严格递增的序列
def almostIncreasingSequence(sequence):
def is_increasing(lst):
for idx in range(len(lst)-1):
if lst[idx] >= lst[idx + 1]:
return False
return True
for idx in range(len(sequence) - 1):
if sequence[idx] >= sequence[idx + 1]:
fixable = is_increasing([*sequence[:idx], *sequence[idx+1:]]) or is_increasing([*sequence[:idx+1], *sequence[idx+2:]])
if not fixable:
return False
return True
对于序列[1,3,2]
,输出应为:
almostIncreasingSequence(sequence) = false;
almostIncreasingSequence(sequence) = true.
您可以从数组中删除3以获得严格递增的序列[1,2]。或者,您可以删除2以获得严格递增的序列[1,3]
我的代码:
def almostIncreasingSequence(sequence):
c= 0
for i in range(len(sequence)-1):
if sequence[i]>=sequence[i+1]:
c +=1
return c<1
你的算法太简单了。您有一个正确的想法,即检查连续的元素对,即较早的元素小于较晚的元素,但需要更多 制作一个例行程序
first\u bad\u pair(sequence)
,检查列表中所有元素对是否有序。如果是,则返回值-1
。否则,返回前面元素的索引:这将是一个从0
到n-2
的值。然后一个可行的算法是检查原始列表。如果有效,可以,但如果无效,请尝试删除较早或以后的违规元素。如果这两种方法中的任何一种都有效,那就好了,否则就不好了
我可以想到其他算法,但这一个似乎是最简单的。如果您不喜欢通过组合原始列表的两个片段而生成的最多两个临时列表,则可以使用更多If
语句在原始列表中进行比较
下面是通过所有测试的Python代码
def first_bad_pair(sequence):
"""Return the first index of a pair of elements where the earlier
element is not less than the later elements. If no such pair
exists, return -1."""
for i in range(len(sequence)-1):
if sequence[i] >= sequence[i+1]:
return i
return -1
def almostIncreasingSequence(sequence):
"""Return whether it is possible to obtain a strictly increasing
sequence by removing no more than one element from the array."""
j = first_bad_pair(sequence)
if j == -1:
return True # List is increasing
if first_bad_pair(sequence[j-1:j] + sequence[j+1:]) == -1:
return True # Deleting earlier element makes increasing
if first_bad_pair(sequence[j:j+1] + sequence[j+2:]) == -1:
return True # Deleting later element makes increasing
return False # Deleting either does not make increasing
如果您确实想避免这些临时列表,下面是另一段代码,它有一个更复杂的对检查例程
def first_bad_pair(sequence, k):
"""Return the first index of a pair of elements in sequence[]
for indices k-1, k+1, k+2, k+3, ... where the earlier element is
not less than the later element. If no such pair exists, return -1."""
if 0 < k < len(sequence) - 1:
if sequence[k-1] >= sequence[k+1]:
return k-1
for i in range(k+1, len(sequence)-1):
if sequence[i] >= sequence[i+1]:
return i
return -1
def almostIncreasingSequence(sequence):
"""Return whether it is possible to obtain a strictly increasing
sequence by removing no more than one element from the array."""
j = first_bad_pair(sequence, -1)
if j == -1:
return True # List is increasing
if first_bad_pair(sequence, j) == -1:
return True # Deleting earlier element makes increasing
if first_bad_pair(sequence, j+1) == -1:
return True # Deleting later element makes increasing
return False # Deleting either does not make increasing
我还在做我的。这样写的,但我不能通过最后3个隐藏测试
def almostIncreasingSequence(sequence):
boolMe = 0
checkRep = 0
for x in range(0, len(sequence)-1):
if sequence[x]>sequence[x+1]:
boolMe = boolMe + 1
if (x!=0) & (x!=(len(sequence)-2)):
if sequence[x-1]>sequence[x+2]:
boolMe = boolMe + 1
if sequence.count(sequence[x])>1:
checkRep = checkRep + 1
if (boolMe > 1) | (checkRep > 2):
return False
return True
这是一个很酷的练习 我是这样做的:
def almostIncreasingSequence(list):
removedIdx = [] #Indexes that need to be removed
for idx, item in enumerate(list):
tmp = [] #Indexes between current index and 0 that break the increasing order
for i in range(idx-1, -1, -1):
if list[idx]<=list[i]: #Add index to tmp if number breaks order
tmp.append(i)
if len(tmp)>1: #If more than one of the former numbers breaks order
removedIdx.append(idx) #Add current index to removedIdx
else:
if len(tmp)>0: #If only one of the former numbers breaks order
removedIdx.append(tmp[0]) #Add it to removedIdx
return len(set(removedIdx))<=1
print('\nThese should be True.')
print(almostIncreasingSequence([]))
print(almostIncreasingSequence([1]))
print(almostIncreasingSequence([1, 2]))
print(almostIncreasingSequence([1, 2, 3]))
print(almostIncreasingSequence([1, 3, 2]))
print(almostIncreasingSequence([10, 1, 2, 3, 4, 5]))
print(almostIncreasingSequence([0, -2, 5, 6]))
print(almostIncreasingSequence([1, 1]))
print(almostIncreasingSequence([1, 2, 3, 4, 3, 6]))
print(almostIncreasingSequence([1, 2, 3, 4, 99, 5, 6]))
print(almostIncreasingSequence([1, 2, 2, 3]))
print('\nThese should be False.')
print(almostIncreasingSequence([1, 3, 2, 1]))
print(almostIncreasingSequence([3, 2, 1]))
print(almostIncreasingSequence([1, 1, 1]))
print(almostIncreasingSequence([1, 1, 1, 2, 3]))
def几乎递增顺序(列表):
removedIdx=[]#需要删除的索引
对于idx,枚举(列表)中的项:
tmp=[]#当前索引和0之间的索引打破了递增顺序
对于范围内的i(idx-1,-1,-1):
如果列表[idx]1:#如果前一个数字中有多个打破了顺序
removedIdx.append(idx)#将当前索引添加到removedIdx
其他:
如果len(tmp)>0:#如果前一个数中只有一个破序
append(tmp[0])#将其添加到removedIdx
返回len(set(removedIdx))这是我的。希望这对您有所帮助:
def almostIncreasingSequence(sequence):
#Take out the edge cases
if len(sequence) <= 2:
return True
#Set up a new function to see if it's increasing sequence
def IncreasingSequence(test_sequence):
if len(test_sequence) == 2:
if test_sequence[0] < test_sequence[1]:
return True
else:
for i in range(0, len(test_sequence)-1):
if test_sequence[i] >= test_sequence[i+1]:
return False
else:
pass
return True
for i in range (0, len(sequence) - 1):
if sequence[i] >= sequence [i+1]:
#Either remove the current one or the next one
test_seq1 = sequence[:i] + sequence[i+1:]
test_seq2 = sequence[:i+1] + sequence[i+2:]
if IncreasingSequence(test_seq1) == True:
return True
elif IncreasingSequence(test_seq2) == True:
return True
else:
return False
def几乎递增顺序(顺序):
#取出边缘盒
如果len(序列)布尔值几乎递增序列(int[]序列){
int length=sequence.length;
if(length==1)返回true;
if(length==2&&sequence[1]>sequence[0])返回true;
整数计数=0;
int指数=0;
布尔iter=true;
while(iter){
索引=检查顺序(顺序,索引);
如果(索引!=-1){
计数++;
索引++;
如果(索引>=长度-1){
iter=假;
}否则如果(索引-1!=0){
如果(sequence[index-1]使用Python3,我从这样的东西开始
def almostIncreasingSequence(sequence):
for i, x in enumerate(sequence):
ret = False
s = sequence[:i]+sequence[i+1:]
for j, y in enumerate(s[1:]):
if s[j+1] <= s[j]:
ret = True
break
if ret:
break
if not ret:
return True
return False
下面是我使用的Python3代码,它运行良好:
def almostIncreasingSequence(sequence):
flag = False
if(len(sequence) < 3):
return True
if(sequence == sorted(sequence)):
if(len(sequence)==len(set(sequence))):
return True
bigFlag = True
for i in range(len(sequence)):
if(bigFlag and i < len(sequence)-1 and sequence[i] < sequence[i+1]):
bigFlag = True
continue
tempSeq = sequence[:i] + sequence[i+1:]
if(tempSeq == sorted(tempSeq)):
if(len(tempSeq)==len(set(tempSeq))):
flag = True
break
bigFlag = False
return flag
def几乎递增顺序(顺序):
flag=False
如果(len(序列)<3):
返回真值
如果(序列==已排序(序列)):
如果(len(序列)=len(set(序列)):
返回真值
bigFlag=True
对于范围内的i(len(序列)):
如果(bigFlag和i
这是我的简单解决方案
def almostIncreasingSequence(sequence):
removed_one = False
prev_maxval = None
maxval = None
for s in sequence:
if not maxval or s > maxval:
prev_maxval = maxval
maxval = s
elif not prev_maxval or s > prev_maxval:
if removed_one:
return False
removed_one = True
maxval = s
else:
if removed_one:
return False
removed_one = True
return True
这适用于大多数情况,但存在性能问题的情况除外
def almostIncreasingSequence(sequence):
if len(sequence)==2:
return sequence==sorted(list(sequence))
else:
for i in range(0,len(sequence)):
newsequence=sequence[:i]+sequence[i+1:]
if (newsequence==sorted(list(newsequence))) and len(newsequence)==len(set(newsequence)):
return True
break
else:
result=False
return result
这也是我的解决方案,
我认为它比这里提出的其他解决方案更干净,所以我将在下面介绍它
它所做的基本上是检查第i个值大于(i+1)个值的索引,如果它找到这样一个索引,则检查删除这两个索引中的任何一个是否会使列表变成递增序列
def almostIncreasingSequence(sequence):
def is_increasing(lst):
for idx in range(len(lst)-1):
if lst[idx] >= lst[idx + 1]:
return False
return True
for idx in range(len(sequence) - 1):
if sequence[idx] >= sequence[idx + 1]:
fixable = is_increasing([*sequence[:idx], *sequence[idx+1:]]) or is_increasing([*sequence[:idx+1], *sequence[idx+2:]])
if not fixable:
return False
return True
您的适度算法在这里失败的原因(除了缺少返回的“=”之外)是,它只是对大于下一个元素的元素进行计数,如果该计数大于1,则返回一个结果
重要的是在每次从列表中删除一个元素后查看列表,并确认它仍然是一个排序列表
我在这方面的尝试非常短,适用于所有场景。它无法满足练习中最后一个隐藏测试集的时间限制
正如问题名称所示,我直接希望将列表与其排序版本进行比较,并在以后处理“几乎”的情况-因此具有几乎递增的顺序。即:
if sequence==sorted(sequence):
.
.
但正如问题所说:
通过一次从数组中移除不超过一个元素来确定是否有可能获得严格递增的序列
我通过在迭代过程中一次删除一个元素开始可视化列表,并检查列表的其余部分是否是其自身的排序版本。因此,我想到了这一点:
for i in range(len(sequence)):
temp=sequence.copy()
del temp[i]
if temp==sorted(temp):
.
.
就是在这里,我可以看到,如果这个条件对于完整列表是真的,那么我们就有了所需的东西-几乎是递增的序列!所以我以这种方式完成了我的代码:
def almostIncreasingSequence(sequence):
t=0
for i in range(len(sequence)):
temp=sequence.copy()
del temp[i]
if temp==sorted(temp):
t+=1
return(True if t>0 else False)
此解决方案在[1,1,1,2,3]等列表上仍然失败。
正如@rory daulton在他的评论中所指出的,我们需要在这个问题中区分“排序”和“递增序列”。当测试[1,1,1,2,3]被排序时,它是在问题中要求的递增序列上。为了处理这个问题,下面是最后的结论
def almostIncreasingSequence(sequence):
t=0
for i in range(len(sequence)):
temp=sequence.copy()
del temp[i]
if temp==sorted(temp):
t+=1
return(True if t>0 else False)
def almostIncreasingSequence(sequence):
t=0
for i in range(len(sequence)):
temp=sequence.copy()
del temp[i]
if temp==sorted(temp) and not(any(i==j for i,j in zip(sorted(temp), sorted(temp)[1:]))):
t+=1
return t>0
def hasIncreasingOrder(slicedSquence, lengthOfArray):
count =0
output = True
while(count < (lengthOfArray-1)) :
if slicedSquence[count] >= slicedSquence[count+1] :
output = False
break
count = count +1
return output
count = 0
seqOutput = False
lengthOfArray = len(sequence)
while count < lengthOfArray:
newArray = sequence[:count] + sequence[count+1:]
if hasIncreasingOrder(newArray, lengthOfArray-1):
seqOutput = True
break
count = count+1
return seqOutput
def almostIncreasingSequence(sequence):
c0,c1=1,1
n=len(sequence)
l1=[]
l2=[]
for i in sequence:
l1.append(i)
l2.append(i)
for i in range(1,n):
if sequence[i-1]>=sequence[i]:
del l1[i]
del l2[i-1]
break
for i in range(1,n-1):
if l1[i-1]>=l1[i]:
c0=0
break
for i in range(1,n-1):
if l2[i-1]>=l2[i]:
c1=0
break
return bool(c0 or c1)
bool almostIncreasingSequence(std::vector<int> sequence) {
/*
if(is_sorted(sequence.begin(), sequence.end())){
return true;
}
*/
int max = INT_MIN;
int secondMax = INT_MIN;
int count = 0;
int i = 0;
while(i < sequence.size()){
if(sequence[i] > max){
secondMax = max;
max = sequence[i];
}else if(sequence[i] > secondMax){
max = sequence[i];
count++;
cout<<"count after increase = "<<count<<endl;
}else {count++; cout<<"ELSE count++ = "<<count<<endl;}
i++;
}
return count <= 1;
}
def almostIncreasingSequence(sequence):
if len(sequence) == 1:
return False
if len(sequence) == 2:
return True
c = 0
c1 = 0
for i in range(1,len(sequence)):
if sequence[i-1] >= sequence[i]:
c += 1
if i != 0 and i+1 < len(sequence):
if sequence[i-1] >= sequence[i+1]:
c1 += 1
if c > 1 or c1 > 1:
return False
return c1 == 1 or c == 1
def almostIncreasingSequence(sequence):
if len(sequence) == 1:
return True
decreasing = 0
for i in range(1,len(sequence)):
if sequence[i] <= sequence[i-1]:
decreasing +=1
if decreasing > 1:
return False
if sequence[i] <= sequence[i-2] and i-2 >=0:
if i != len(sequence)-1 and sequence[i+1] <= sequence[i-1]:
return False
return True
bool almostIncreasingSequence(std::vector<int> a)
{
int n=a.size(), p=-1, c=0;
for (int i=1;i<n;i++)
if (a[i-1]>=a[i])
p=i, c++;
if (c>1) return 0;
if (c==0) return 1;
if (p==n-1 || p==1) return 1;
if (a[p-1] < a[p+1]) return 1;
if (a[p-2] < a[p]) return 1;
return 0;
}
def almostIncreasingSequence(sequence):
removed = 0
previous_maximum = maximum = float('-infinity')
for s in sequence:
if s > maximum:
# All good
previous_maximum = maximum
maximum = s
elif s > previous_maximum:
# Violation - remove current maximum outlier
removed += 1
maximum = s
else:
# Violation - remove current item outlier
removed += 1
if removed > 1:
return False
return True
import numpy as np
def IncreasingSequence(sequence):
temp=sequence.copy()
temp.sort()
if (len(sequence) != len(set(sequence))):
return False
if (sequence==temp):
return True
return False
def almostIncreasingSequence(sequence):
for i in range(len(sequence)-1):
if sequence[i] >= sequence[i+1]:
sequence_temp=sequence.copy()
sequence_temp.pop(i)
# print(sequence_temp)
# print(IncreasingSequence(sequence_temp))
if (IncreasingSequence(sequence_temp)):
return True
# Might be the neighbor that is worth removing
sequence_temp=sequence.copy()
sequence_temp.pop(i+1)
if (IncreasingSequence(sequence_temp)):
return True
return False
def almostIncreasingSequence(sequence):
if len(sequence)<=2:
return True
def isstepdown(subsequence):
return [a>=b for a,b in zip(subsequence, subsequence[1:])]
stepdowns = isstepdown(sequence)
n_stepdown = sum(stepdowns)
if n_stepdown>1:
return False
else:
sequence2 = sequence.copy()
sequence.pop(stepdowns.index(True))
stepdowns_temp = isstepdown(sequence)
n_stepdown = sum(stepdowns_temp)
sequence2.pop(stepdowns.index(True)+1)
stepdowns_temp = isstepdown(sequence2)
n_stepdown += sum(stepdowns_temp)
if n_stepdown<=1:
return True
else:
return False