Определите, содержит ли массив почти возрастающую последовательность

Учитывая последовательность целых чисел как массив, определите, возможно ли получить строго возрастающую последовательность, удалив не более одного элемента из массива.

Для последовательности = [1, 3, 2, 1]выход должен быть

almostIncreasingSequence(sequence) === false

В этом массиве нет ни одного элемента, который можно было бы удалить, чтобы получить строго возрастающую последовательность.

Для последовательности = [1, 3, 2]выход должен быть

almostIncreasingSequence(sequence) === true

Как вы можете удалить 3 из массива, чтобы получить строго возрастающую последовательность [1, 2], Кроме того, вы можете удалить 2, чтобы получить строго возрастающую последовательность [1, 3],

Вот что у меня так далеко:

function almostIncreasingSequence(sequence) {
  //compare current int to previous, return true if greater than 
  //remove int at index and compare with new values, return false if comparison fails
  var result = false;

  for(var i = 0; i < sequence.length; i++){
     var newSequence = sequence.slice();
     var subSequence = newSequence.splice(i, 1);

     for(var j = 0; j < newSequence.length - 1; j++){
        if(newSequence === newSequence.sort((a,b) => a < b).reverse()){
          result = true;
        } 
     }         
  }
  return result;
}

Я пытаюсь выяснить, как решить эту проблему. Я чувствую, что я очень близок, но по какой-то причине, когда я вызываю reverse в условном выражении, он также сортирует переменную newSequence. Он сортирует две переменные в условной, а не одну. В результате это решает к истине. Мне не понятно, почему это происходит. Любые отзывы приветствуются.

2 ответа

Решение

Нет необходимости использовать вложенный цикл или создавать новые массивы. Это можно сделать за O(n) раз:

function almostIncreasingSequence(sequence) {
    var prev = -Infinity,
        beforePrev = -Infinity,
        allowExceptions = true;
    
    for (var curr of sequence) {
        // Is order not maintained?
        if (curr <= prev) {
            // Give up when this is not the first exception
            if (!allowExceptions) return false;
            allowExceptions = false;
            // Decide whether to skip the current or previous value
            if (curr > beforePrev) prev = curr;
        } else { // Normal case: keep track of two preceding values
            beforePrev = prev;
            prev = curr;
        }
    }
    return true;
}

console.log(almostIncreasingSequence([1,5,3,4,8])); // true
console.log(almostIncreasingSequence([1,5,0,6,8])); // true
console.log(almostIncreasingSequence([1,5,0,4,8])); // false

sort() изменяет массив на месте, он не возвращает новый массив. И вы не можете сравнить содержимое двух массивов, используя ==, так что это не хороший способ определить, отсортирован ли массив. Вы можете просто перебрать массив, проверяя, больше ли каждый элемент, чем предыдущий.

function almostIncreasingSequence(sequence) {
  for (var i = 0; i < sequence.length; i++) {
    var newSequence = sequence.slice();
    newSequence.splice(i, 1);
    var isSorted = true;
    for (j = 1; isSorted && j < newSequence.length; j++) {
      if (newSequence[j] <= newSequence[j-1]) {
        isSorted = false;
      }
    }
    if (isSorted) {
      return true;
    }
  }
  return false;
}

console.log(almostIncreasingSequence([1, 3, 2, 1]));
console.log(almostIncreasingSequence([1, 3, 2]));
console.log(almostIncreasingSequence([1, 2, 3, 4, 5, 3]));
console.log(almostIncreasingSequence([8, 1, 2, 3, 4, 5]));
console.log(almostIncreasingSequence([8, 1, 2, 2, 4, 5]));

Другие вопросы по тегам