Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 求解几乎递增的序列(代码战)_Python_Arrays - Fatal编程技术网

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