Solve almostIncreasingSequence (Codefights)

后端 未结 15 1192
谎友^
谎友^ 2020-12-08 07:35

Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.

相关标签:
15条回答
  • 2020-12-08 08:10

    I'm still working on mine. Wrote it like this but I can't pass the last 3 hidden tests.

    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
    
    0 讨论(0)
  • 2020-12-08 08:10

    This was a pretty cool exercise.

    I did it like this:

    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]))
    
    0 讨论(0)
  • 2020-12-08 08:10

    This is my Solution,

    def almostIncreasingSequence(sequence):

    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
    
    0 讨论(0)
  • 2020-12-08 08:18

    The reason why your modest algorithm fails here (apart from the missing '=' in return) is, it's just counting the elements which are greater than the next one and returning a result if that count is more than 1.

    What's important in this is to look at the list after removing one element at a time from it, and confirm that it is still a sorted list.

    My attempt at this is really short and works for all scenario. It fails the time constraint on the last hidden test set alone in the exercise.

    As the problem name suggests, I directly wanted to compare the list to its sorted version, and handle the 'almost' case later - thus having the almostIncreasingSequence. i.e.:

    if sequence==sorted(sequence):
       .
       .
    

    But as the problem says:

    determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array (at a time).

    I started visualizing the list by removing an element at a time during iteration, and check if the rest of the list is a sorted version of itself. Thus bringing me to this:

    for i in range(len(sequence)):
        temp=sequence.copy()
        del temp[i]
        if temp==sorted(temp):
            .
            .
    

    It was here when I could see that if this condition is true for the full list, then we have what is required - an almostIncreasingSequence! So I completed my code this way:

    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)
    

    This solution still fails on lists such as [1, 1, 1, 2, 3]. As @rory-daulton noted in his comments, we need to differentiate between a 'sorted' and an 'increasingSequence' in this problem. While the test [1, 1, 1, 2, 3] is sorted, its on an increasingSequence as demanded in the problem. To handle this, following is the final code with a one line condition added to check for consecutive same numbers:

    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
    

    As this still fails the execution time limit on the last of the test (the list must be really big), I am still looking if there is a way to optimize this solution of mine.

    0 讨论(0)
  • 2020-12-08 08:18

    Here's my simple solution

    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
    
    0 讨论(0)
  • 2020-12-08 08:19

    Well, here's also my solution, I think it's a little bit cleaner than other solutions proposed here so I'll just bring it below.

    What it does is it basically checks for an index in which i-th value is larger than (i+1)-th value, if it finds such an index, checks whether removing any of those two makes the list into an increasing sequence.

    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
    
    0 讨论(0)
提交回复
热议问题