8

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

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

We can remove 3 from the array to get the strictly increasing sequence [1, 2]. Alternately, we can remove 2 to get the strictly increasing sequence [1, 3].

The function must return true if it is possible to remove one element from the array in order to get a strictly increasing sequence, otherwise return false.

Here is what i have already tried , but it doesnt work for all situations

function almostIncreasingSequence(sequence) {
    for (var i = 0; i < sequence.length; i++) {
        if (sequence[i] > sequence[i + 1]) {
            sequence.splice(i, 1);
           return true;
        };
        return false;
    };
}
Norayr Ghukasyan
  • 93
  • 1
  • 1
  • 6
  • 1
    Does this answer your question? [Solve almostIncreasingSequence (Codefights)](https://stackoverflow.com/questions/43017251/solve-almostincreasingsequence-codefights) – sanmai Jun 13 '20 at 05:17

26 Answers26

16

function almostIncreasingSequence(sequence) {
  var found = false;
  for (var i=0;i<sequence.length;i++) {
    if(sequence[i] <= sequence[i-1]) {
      if(found) {
        return false;
      }
      found = true;
      
      if(i === 1 || i + 1 === sequence.length) {
        continue;
      }
      else if (sequence[i] > sequence[i-2]) {
        sequence[i-1] = sequence[i-2];
      }
      else if(sequence[i-1] >= sequence[i+1]) {
        return false;
      }
    }
  }
  return true;
}
Vipin PS
  • 422
  • 4
  • 5
2

Here is my solution.

First I look for a decreasing sequence. If none, then return true If there is a decreasing sequence inside the array, I create two more arrays excluding the two items in the decreasing sequence, and check those two new arrays. If one of them has no decreasing sequences, then return true, otherwise return false

function indexOfFail(sequence) {
    let index = null;
    for (let i = 0; i < sequence.length -1; i++) {
        if (sequence[i] >= sequence[i + 1]) {
            index = i;
            break;
        }
    }
    return index;
}

function almostIncreasingSequence(sequence) {

    let index = indexOfFail(sequence);
    if (index == null) return true;

    let tmp1 = sequence.slice(0);
    tmp1.splice(index, 1); //remove failed item
    if (indexOfFail(tmp1) == null) return true;
    
    let tmp2 = sequence.slice(0);
    tmp2.splice(index + 1, 1); //remove next item to failed item
    if (indexOfFail(tmp2) == null) return true;
    
    return false;

}
1

Here is my answer

function almostIncreasingSequence(sequence) {
    if (isIncreasingSequence(sequence)) {
        return true;
    }



    for (var i = 0; i < sequence.length > 0; i++) {
        var tmpSequence = sequence.slice(0); // copy original array

        tmpSequence.splice(i, 1);
        if (isIncreasingSequence(tmpSequence)) {
            return true;
        }
    }

    return false;
}

function isIncreasingSequence(sequence) {
    for (var i = 0; i < sequence.length - 1; i++) {
        if (sequence[i] >= sequence[i + 1]) {
            return false;
        }
    }

    return true;
}

almostIncreasingSequence([1, 3, 2, 1]); // false
almostIncreasingSequence([1, 3, 2]); // true
Vasil Nikolov
  • 1,112
  • 10
  • 17
1

function almostIncreasingSequence(seq) {
  var bad=0
  for(var i=1;i<seq.length;i++) if(seq[i]<=seq[i-1]) {
    bad++
    if(bad>1) return false
    if(seq[i]<=seq[i-2]&&seq[i+1]<=seq[i-1]) return false
  }
  return true
}
Vipin PS
  • 422
  • 4
  • 5
1

My Python3 answer:

O(n) time and O(1) space

def almostIncreasingSequence(sequence):
        
    counter = 0
    
    for idx in range(1, len(sequence)):
        
        # n is smaller or equal to n-1
        if sequence[idx] <= sequence[idx-1]:
            counter += 1
            
            # checking if index to be checked is within bounds
            if idx - 2 >= 0 and idx + 1 <= len(sequence)-1:
                # n is smaller or equal to n-1 and n+1 is smaller or equal to n-1
                print(sequence[idx], sequence[idx-2], sequence[idx+1], sequence[idx-1])
                if sequence[idx] <= sequence[idx-2] and sequence[idx+1] <= sequence[idx-1]:
                    counter += 1
        print(counter)      
    # return true if 1 or 0 in counter otherwise return false
    return counter <= 1
nigh_anxiety
  • 1,428
  • 2
  • 4
  • 12
Joao Henrique
  • 547
  • 5
  • 13
1

I know post is old, but here is php solution to the problem

function almostIncreasingSequence($sequence){

$error = false;
$check_current_again = false;

for ($i = 0; $i + 1 < count($sequence); $i++) {
    $next = $i + 1;

    if($check_current_again){
        $i = $i - 1;            
    }

    $check_current_again = false;
    if($sequence[$i] >= $sequence[$next]){
        if($error){
            return false;
        }

        $error = true;

        if($i > 0 && $sequence[$i -1] >= $sequence[$i + 1]){
            $check_current_again = true;
        }
    }       
}
return true;

}

0

I think sequence is not almost increasing if there is more than one number which is smaller than it's previous number:

function almostIncreasingSequence(sequence) {
    var found = 0;
    sequence.forEach((el, index) => {
        var next= sequence[index + 1] || Infinity;
        if (el >= next) {
            found++;
        }
    });
    return found <= 1;
}
console.log("1, 3, 2, 1: ", almostIncreasingSequence([1, 3, 2, 1]));
console.log("1, 3, 2: ", almostIncreasingSequence([1, 3, 2]));
console.log("1, 2, 5, 5, 5: ", almostIncreasingSequence([1, 2, 5, 5, 5]));

And even simpler and shorter with array.filter:

function almostIncreasingSequence(sequence) {
    return sequence.filter((it, index) => it >= (sequence[index + 1] || Infinity)).length <= 1;
}
console.log("1, 3, 2, 1: ", almostIncreasingSequence([1, 3, 2, 1]));
console.log("1, 3, 2: ", almostIncreasingSequence([1, 3, 2]));
console.log("1, 2, 5, 5, 5: ", almostIncreasingSequence([1, 2, 5, 5, 5]));
console.log("1, 2, 4, 5, 5: ", almostIncreasingSequence([1, 2, 4, 5, 5]));
Faly
  • 13,291
  • 2
  • 19
  • 37
0

Solution of a question:

function almostIncreasingSequence(sequence) {
  var inc = true;
  for (var i = 0; i < sequence.length; i++) {
    if (sequence[i] >= sequence[i + 1]) {
      if (inc) {
        inc = false;
      }
      else {
        return false;
      }
    }
  };
  return true;
}

console.log(almostIncreasingSequence([1, 3, 2, 1])); // false
console.log(almostIncreasingSequence([1, 3, 2])); // true
ollazarev
  • 1,076
  • 8
  • 26
0
function Test(arr){
    var set_once = false;
    for (i=0; i<arr.length; i++){
        if(arr[i+1] <= arr[i]){
            if(!set_once){
                set_once = true;
                arr.splice(i+1,1);
                i = i-1;
                }else{
                 return false;
            }
        }
    }
    return true
}
Mohan
  • 172
  • 1
  • 11
0

Algorithm: An almost increasing sequence can only have one number that is smaller than its previous number, and it must not equal than the number before its previous number. Also, the previous number must not equal to the number after the current number.

Illustration: Consider the following 4 numbers:

a, b, c, d

a and c must not equal to each other, so are b and d. We must nest this condition within (b > c) condition.

Actual JavaScript code:

const almostIncreasingSequence = seq => {
  let decrementCount = 0;

  for (let i = 1; i < seq.length - 1; i ++) {
    if (seq[i] <= seq[i - 1]) {
      decrementCount++;
      if (seq[i] <= seq[i - 2] && seq[i + 1] <= seq[i - 1]) {
        return false;
      }
    }
  }

  return decrementCount <= 1;
}
WebDeg Brian
  • 802
  • 1
  • 7
  • 21
  • It's not fully correct, fails on [1, 2, 5, 5, 5] and [10, 1, 2, 3, 4, 5, 6, 1] and [1, 3, 2, 1] – Richard Nov 08 '18 at 01:24
0

Here is a solution in PHP

function almostIncreasingSequence($sequence) {
    $foundOne = false;

    for ($i = -1, $j = 0, $k = 1; $k < count($sequence); $k++) {
        $deleteCurrent = false;
        if ($sequence[$j] >= $sequence[$k])
        {
            if ($foundOne)
            {
                return false;
            }
            $foundOne = true;
            if ($k > 1 && $sequence[$i] >= $sequence[$k])
            {
                $deleteCurrent = true;
            }
        }
        if (!$foundOne)
        {
            $i = $j;
        }
        if (!$deleteCurrent)
        {
            $j = $k;
        }
    }
    return true;
}

hoangdv
  • 15,138
  • 4
  • 27
  • 48
0
  static bool almostIncreasingSequence(int[] sequence)
    {
        int counter = 0;           
        if (sequence.Length <3)
            return true;

        int prevNo = sequence.Min() - 1;

        for (int i = 0; i < sequence.Length; i++)
        {
            if (counter < 2)
            {

                if (prevNo < sequence[i])
                    prevNo = sequence[i];
                else
                {
                    if (i == 0 || i == sequence.Length - 1)
                    {
                        counter += 1;
                    }
                    else if (i > 1)
                    {
                        if (sequence[i] <= sequence[i - 2])
                        {
                            if (prevNo < sequence[i + 1])
                            {
                                counter += 1;
                            }
                            else
                            {
                                counter += 2;
                            }

                        }
                        else
                        {
                            prevNo = sequence[i];
                            counter = counter + 1;
                        }
                    }
                   // {
                        if (i < sequence.Length - 2)
                        {
                            if (sequence[i] < sequence[i + 1])
                            {
                                counter = counter + 1;
                                prevNo = sequence[i];
                            }
                            else
                            {
                                counter += 1;
                            }
                        }
                 //   }


                    if (counter >= 2)
                        return false;
                }
            }

        }
        return true;

    }
Rose
  • 1
  • 1
  • It helps more if you supply an explanation why this is the preferred solution and explain how it works. We want to educate, not just provide code. – the Tin Man May 24 '20 at 18:40
0

Here is a python3 implementation of the same. took me a while. not that clean of a code But take O(N) time and O(1) space so that's ok I guess.
In this case, I had used an approach where I maintained a counter variable and a pointer I increased the counter by 1 each time the sequence was not in an increasing fashion. and maintained a pointer to the index of the element which was out of sequence. if the counter had value more than 1 then the sequence is breaking at 2 points and it almost increasing sequence can not be achieved. if the sequence was already in place then the counter would be zero. the tricky part comes when the counter is 1 here we make use of the index variable which we maintained that is p if the c == 1 and the index is 0 or the length of sequence then the element which is breaking the sequence is at the start or end which can be removed to obtain an increasing sequence.

and if that's, not the case. we check for the adjacent values and they are breaking any order or not. if they are not breaking the order return True else its False. Hope I was able to help. Forgive the Bad indentation. I am new to the code editor at StackOverflow

def almostIncreasingSequence(sequence):
p = -1
c = 0
for i in range(1, len(sequence)):
    if sequence[i-1] >= sequence[i]:
        p = i
        c += 1
if c > 1:
    return False
if c == 0:
    return True

if p == n -1 or p == 1:
    return True

if sequence[p-1] < sequence[p+1] or sequence[p-2] < sequence[p]:
    return True
return False
Akash g krishnan
  • 469
  • 5
  • 16
0

Here's an extremely dirty version of it. Lately, I've been trying to make solutions that are language agnostic, so that I don't become dependent on functions for problem solving, but learn them later for whatever language I specialize in.

Perhaps one of the dirtiest ways to do it, but time complexity is O(3N) = O(N). Space complexity is O(2N).

The logic comes from the fact that you only need to check for ONE missing element, so there is no need to do anything fancy, just save the index of that element and check the array without that element. Because sometimes you can run into another element being the issue (particularly in the case of duplicates), you should save the index of both problem elements.

Again, extremely dirty, but it passes all test cases and time constraints.

function almostIncreasingSequence(sequence) {
   let wrongindex = 0;
   let nextwrongindex = 0;
   for(let i = 0; i < sequence.length - 1; i++){
      if(sequence[i] >= sequence[i + 1]){
          wrongindex = i;
          nextwrongindex = i+1;
      }
   }
   let newArr = [];
   let newArr2 = [];
   for(let i = 0; i < sequence.length; i++){
    if(i != wrongindex){
     newArr.push(sequence[i]);
    }
   }
   
   for(let i = 0; i < sequence.length; i++){
    if(i != nextwrongindex){
     newArr2.push(sequence[i]);
    }
   }
   
   let isincreasingcount = 0;;
   
   for(let i = 0; i < newArr.length - 1; i++){
     if(newArr[i] >= newArr[i+1]){
         isincreasingcount++;
     }
   }
   
   for(let i = 0; i < newArr2.length -1; i++){
     if(newArr2[i] >= newArr2[i+1]){
         isincreasingcount++;
     }
   }
   if(isincreasingcount > 1){
       return false;
   }
   return true;
}
Greg
  • 31
  • 5
0
  • $sequence = [0, -2, 6, 8] (Expected Output: true)
  • $sequence = [123, -17, -5, 1, 2, 12, 41, 45] (Expected Output: true)
  • $sequence = [10, 1, 2, 3, 4, 5, 6, 1] (Expected Output: false)
  • $sequence = [3, 5, 62, 98, 3] (Expected Output: true)
  • $sequence = [40, 49, 63, 10, 22, 30] (Expected Output: false)

This almostIncreasingSequence function will return the given Array is Increasing Sequence or not. You can try the above array examples.

print_r(almostIncreasingSequence($sequence));

function almostIncreasingSequence($sequence){

$found = 0;
$status = true;
for ($i=0;$i<sizeof($sequence);$i++) {
  if(($sequence[$i] <= @$sequence[$i-1]) && isset($sequence[$i-1])) {
    $found++;
    if($found > 1) $status = false; 
    if($sequence[$i] <= $sequence[$i-2] && $sequence[$i+1] <= $sequence[$i-1] && isset($sequence[$i+1])) $status = false;
  }      
}
return (($status == 0) ? $status : true);
}
0

Just for the diversity. That's how I solved it.

function almostIncreasingSequence(sequence) {

    let failsSeq = new Array(sequence.length).fill(0);

    for(let i=0; i<sequence.length; i++) {
        if (sequence[i+1] && sequence[i] >= sequence[i+1]) {
            failsSeq[i] += 1;
            if (sequence[i+2] && sequence[i] >= sequence[i+2]) {
                failsSeq[i] += 1;
            }
            if (sequence[i-1] && sequence[i+1] && sequence[i-1]>=sequence[i+1]) {
                failsSeq[i] += 1;
            }
        }
    }
    
    const failsTotal = failsSeq.reduce( (acc, currValue) => acc + currValue);
    const failSingle = failsSeq.filter( (item) => item >= 2 ).length;
    
   
    if (failSingle === 1 && failsTotal === 2) {
        return true;
    }
    
    return failsTotal > 1 ? false : true;

}
Janiis
  • 1,478
  • 1
  • 13
  • 19
0

for eg 1,2,[5,3],6

We can solve this by 2 pointers, p2 will be ahead of p1 by 1 at the beginning. Once we found that, from the eg, 5 > 3, we need to skip each and check if the sequence is still valid, for that reason we call increasingSeq(), and skip 5 by (p1 -1). Then we skip 3 by (p2 + 1).

Once we skip those we start comparing the sequence again.

function almostIncreasingSequence(sequence) {
    if (sequence.length < 2) return true;
    let p1 = 0;
    let p2 = 1;

    while(p2 < sequence.length) {
        if (sequence[p1] >= sequence[p2]) {
            const a = increasingSeq(sequence, p1 - 1, p2);
            const b = increasingSeq(sequence, p1, p2 +1 )
            return a || b
        }
        p1 = p2;
        p2++
    }
    return true;
}

function increasingSeq(sequence, p1, p2) {
    while(p2 < sequence.length) {
        if (sequence[p1] >= sequence[p2]) return false;
        p1 = p2;
        p2++
    }
    return true;
}
Amit Lopes
  • 41
  • 6
  • Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes – Ran Marciano Mar 21 '21 at 05:59
0
boolean almostIncreasingSequence(int[] sequence) {
int n = sequence.length;
if (n == 2)
{
    return true;
}
int count = 0;
boolean result = true;
for (int i = 0; i < sequence.length - 1; i++)
{

    if (sequence[i] >= sequence[i+1])
    {
        count++;
        if (i != 0 && sequence[i-1] >= sequence[i+1])
        {
            result = false;
        }
        if (i < n-2 && sequence[i] < sequence[i+2])
        {
            result = true;
        }
        if (i == n - 2)
        {
            result = true;
        }
    }              
}
return (count < 2 && result);

}

mihsa
  • 21
  • 5
  • 2
    Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Tyler2P Aug 05 '21 at 16:57
0

Here is a complete working solution:

function almostIncreasingSequence($s) 
{
  $bad=0;
  
  for($i=1;$i<count($s);$i++)
  {
      if($s[$i]<=$s[$i-1]) $bad++;
  
      if($bad>1) return false;
      
      if(isset($s[$i+1]) && isset($s[$i-2]) && $s[$i]<=$s[$i-2] && $s[$i+1]<=$s[$i-1]) return false;
  }
  
  return true;
}
0

This is my optimized solution with python:

def solution(sequence):
    if len(sequence) > 2:
        for i in range(len(sequence)-1):
            if sequence[i]>sequence[i+1]:
                news = sequence[:i]+sequence[i+1:]
                if news == sorted(news) and len(set(news)) == len(news):
                    return True
                else:
                    news = sequence[:i+1]+sequence[i+2:]
                    if news == sorted(news) and len(set(news)) == len(news):
                        return True
        return False
    else:
        return True
Houda M
  • 123
  • 1
  • 8
  • This solution doesn't appear to be correct. Any sequence that is already increasing (example `[1, 2, 3, 4]`) or which contains a single duplicate value, `[1, 2, 2, 3]`, returns `False` – nigh_anxiety Jul 03 '23 at 17:11
0

I've checked out that most proposals fails with the new tests added to codeSignal. My approach is not quite optimal but it's easy to understand.

First, I store into a hashmap the problematic indexes (the current and the previous one). After that you can run simulations of the array without the problematic items. It just simply minimizes the brute force approach and it passes all the test even with high amount of items.

Time complexity: O(N+N) Space complexity: O(1)

Tests passed: 38/38. Sample tests: 19/19 Hidden tests: 19/19 Score: 300/300

Edited: I added a "break" after first problematic number encountered in order to just handle the first issue. So time complexity now is better.

bool almostIncreasingSequence(vector<int> sequence) {
    int length = sequence.size();
    if (length < 2) {
        return false;
    }
    
    // Store invalid indexes
    unordered_map<int, int> m;
    for(int i=1;i<length;++i) {        
        if (sequence[i-1] >= sequence[i]) {
            m[i-1]++;
            m[i]++;
            break; // new added
        }
    }
    // Scan invalid indexes
    for(auto it : m) {
        int prev = -1;
        int numInvalid = 0;
        const int id = it.first;

        // Simulate
        for(int i=0;i<length;++i) {
            if (id!=i) { // Do not add the problematic one
                if (prev != -1 && prev >= sequence[i]) {
                    ++numInvalid;
                    break;
                }
                prev = sequence[i];
            }
        }
        if (numInvalid == 0) {
            return true;
        }
    }
    return false;
}
0

Here is my PHP solution:

function almostIncreasingSequence($sequence) {   
    for($i=0;$i<count($sequence);$i++) {
        $input = $sequence;
        array_splice($input, $i, 1);
        if(count($input) == count(array_unique($input))) {
            $solution = $input;
            sort($input);           
            if($solution == $input) {   
                return true;
            }
        }
    }
    return false;
}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 18 '22 at 12:04
0

My javascript answer for strictly increasing sequence.

function solution(sequence) {
        
    for(let i =0;i<sequence.length;i++){
        // first iteration
        if((sequence[i]-sequence[i+1])>=0){
           sequence.splice((i),1);
           console.log('5', sequence);
        // check again    
           for(let i = 0;i<sequence.length;i++){
               
           if((sequence[i]-sequence[i+1])>=0){
               console.log('9', sequence);
               return false;
           }
           
           }
           
           
        }
        
    };
    return true
 }
ruud
  • 743
  • 13
  • 22
0
boolean solution(int[] sequence) {
    int count = 0;
    
    for (int i = 1; i < sequence.length; i++) {
        if (sequence[i] <= sequence[i-1]) {
            // Increase count if we found a replace.
            // return false if we found more than one 
            // replacements
            count++;
            if (count > 1) {
                return false;
            }
            
            // Make sure you are within bounds of the array
            // compare current index value with with previous
            // two indices.
            // finally compare values before and after the current
            // index.
            if (i - 2 > -1 && i+1 < sequence.length 
                && sequence[i] <= sequence[i-2] 
                && sequence[i+1] <= sequence[i-1]) {
                return false;
            }
        }
    }
    return true;
}

KingNOB
  • 107
  • 1
  • 6
0

Here's my solution.

function solution (sequence) {
  // Make a copy since we'll be splicing away at the array.
  const copy = [...sequence]

  // Iterate the copy.
  for (let i = 0; i < copy.length; i++) {
    const prev = copy[i - 1]
    const curr = copy[i]
    const next = copy[i + 1]
    
    // If the previous value is neither undefined nor less than current,
    // and the next value is neither undefined nor greater than current...
    if (!((prev === undefined || prev < curr) && (next === undefined || next > curr))) {
      // Splice the offending value.
      const splice = next <= prev ? i + 1 : i
      copy.splice(splice, 1)
      
      // Jump back a spot and continue along.
      i--
    }
  }

  // If we've trimmed more than 1, we've lost.
  return sequence.length - copy.length < 2
}
Charlie Schliesser
  • 7,851
  • 4
  • 46
  • 76
0

Here is a solution using a generator to yield each possible sub-array and test if any of them holds a strictly growing sequence.

function almostIncreasingSequence(sequence) {
  function* subArrays(array) {
    for (let i = 0; i < array.length; i++) {
      yield [...array.slice(0, i), ...array.slice(i + 1)];
    }
  }

  return Array.from(subArrays(sequence)).some((subArray) =>
    subArray.every((element, index) => index === 0 || element > subArray[index - 1])
  );
}

// Example usage
console.log(almostIncreasingSequence([1, 3, 2, 1])); // Output: false
console.log(almostIncreasingSequence([1, 3, 2])); // Output: true
psychoslave
  • 2,783
  • 3
  • 27
  • 44