【问题标题】:Check if an array is a subsequence of another arrayCheck if an array is a subsequence of another array
【发布时间】:2022-12-19 06:38:32
【问题描述】:

Given this arrays I want to check if "sequence" is a subsequence of "array", meaning all the numbers exist in the original array and in the same order:

array = [5, 1, 22, 25, 6, -1, 8, 10];
sequence = [1, 6, -1, 10];

Not sure why my code doesn't work.

function isValidSubsequence(array, sequence) {
    let seqIdx = 0;
    let arrId = 0;
    for (const value of sequence ){
        if (seqIdx === sequence.length) break;
        if (array[arrId] === value) {
            seqIdx++;
            arrId++;
        }
    }

    return seqIdx === sequence.length
}

【问题讨论】:

  • Subset... or substring?
  • This should work const result = sequence.every(el => array.includes(el));
  • @HariHaravelan that won't account for order
  • @Phil Yes right, my bad
  • Thanks! it worked and makes sense

标签: javascript arrays subsequence


【解决方案1】:

Remove arrIdx.

In a for...of loop the index of array isn't needed in this case since value progresses on each iteration.

Remove the first flow control statement.

if (seqIdx === sequence.length) break;

There's no need to interupt the loop. The Boolean returned outside of the loop is sufficient.

Change the second flow control statement to monitor sequence[seqIdx] not array

if (sequence[seqIdx] === value) {
  seqIdx++;
}

The key to this algorithm is to progress through array one number at a time (as is the norm), but not the sequence. The counter, seqIdx, only progresses on a match so basically if sequence ends before or at the end of the loop it is a valid subsequence.

const arr = [5, 1, 22, 25, 6, -1, 8, 10];
const seq = [1, 6, -1, 10];

function isValidSubsequence(array, sequence) {
  let seqIdx = 0;
  for (const value of array) {
    if (sequence[seqIdx] === value) {
      seqIdx++;
    }
  }
  return seqIdx === sequence.length;
};
console.log(isValidSubsequence(arr, seq));

【讨论】:

  • for (const value of sequence) <--- I wonder if there's any chance this needs to be for (const value of array)? Or, may be I'm missing something here.
  • OOpps! Updated thanks.
  • Thanks! it worked and makes sense
【解决方案2】:

Your solution doesn't work because it never moves past the first entry in array. You never increment any of your indexes unless the sequence value matches array[arrId].

I'd use Array.prototype.indexOf() with the second fromIndex parameter to create a shrinking window of array as you search. If you ever reach an iteration of sequence that cannot be found, you know it fails the test

function isValidSubsequence(array, sequence) {
  let index = -1;
  for (const value of sequence) {
    index = array.indexOf(value, index + 1); // find the next sequence value
    if (index === -1) {
      return false; // not found, return false immediately
    }
  }
  return true;
}

const array = [5, 1, 22, 25, 6, -1, 8, 10];
const sequence = [1, 6, -1, 10];

console.log("valid sub-sequence:", isValidSubsequence(array, sequence));
console.log("out of order:", isValidSubsequence(array, [25, 22]));
console.log("unknown elements:", isValidSubsequence(array, [5, 11]));

【讨论】:

  • Thanks! it worked and makes sense
  • Should be slice.slice(index + 1) to handle repeats such as isValidSubsequence([ 1, 1, 2 ], [ 1, 1, 1, 2 ]) correctly.
  • I think the second argument of indexOf can be used instead of using slice to shrink the window.
  • @SebastianSimon nice one, I hadn't accounted for repeated elements in the sequence correctly.
【解决方案3】:

You can achieve it in a simple way by finding the index of sequence array elements from the original array and then check if the indexed array is sorted or not.

Demo :

const array = [5, 1, 22, 25, 6, -1, 8, 10];
const sequence = [1, 6, -1, 10];

// Find index of the elements from the original array.
const indexArr = sequence.map((item) => array.indexOf(item));

// Now test if this indexed array is sorted or not to check if sequence array having same order as per the original array.
function isSorted(arr) {
  var i = 0;
  var last = arr.length - 1;
  return (function check() {
    return (i >= last) || (arr[i] <= arr[++i] && check());
  })();
}

console.log(isSorted(indexArr))

【讨论】:

    猜你喜欢
    • 2022-12-01
    • 2019-07-14
    • 2022-12-01
    • 2022-12-02
    • 2019-03-11
    • 2022-12-02
    • 2022-12-02
    • 2022-12-26
    • 1970-01-01
    相关资源
    最近更新 更多