Number of Subarrays That Match a Pattern II - KMP Algorithm [JS]

Description 

Solution: KMP Algorithm

Create an array relation of length n - 1 representing the relationship between each pair of adjacent numbers in nums.

  • nums[i] < nums[i + 1]: 1
  • nums[i] === nums[i + 1]: 0
  • nums[i] > nums[i + 1]: -1

From there, the problem boils down to finding the number of exact matches of pattern in relation.
Use the KMP algorithm to find the number of matches in O(n + m).

n = length of numsm = length of pattern
Time Complexity: O(n + m)
Space Complexity: O(n + m)

var countMatchingSubarrays = function(nums, pattern) {
  let n = nums.length, relation = Array(n - 1).fill(0);
  for (let i = 0; i < n - 1; i++) {
    if (nums[i] < nums[i + 1]) relation[i] = 1;
    else if (nums[i] === nums[i + 1]) relation[i] = 0;
    else relation[i] = -1;
  }
  return kmp(relation, pattern);
};

function kmp(arr, subarray) {
  let lps = getLPS(subarray);
  let n = arr.length, m = subarray.length;
  let i = 0, j = 0;
  let matches = 0;
  while (j < n) {
    if (arr[j] === subarray[i]) { 
      i++, j++; 
      if (i === m) matches++;
    } else if (i > 0) {
      i = lps[i - 1]; // rollback
    } else j++; // i is 0, so we move j forward
  }
  return matches;
}

function getLPS(arr) {
  let n = arr.length, lps = Array(n).fill(0);
  let i = 0, j = 1;
  while (j < n) {
    if (arr[i] === arr[j]) {
      lps[j++] = ++i;
    } else if (i > 0) {
      i = lps[i - 1];
    } else j++;
  }
  return lps;
}

Comments

Popular posts from this blog

Maximum Value of an Ordered Triplet II - Two Solutions [JS]

Maximum Sum of Distinct Subarrays With Length K - Sliding Window w/ Two Pointers & Set [JS]

Sum of Prefix Scores of Strings - Trie [JS]

Maximum Count of Positive Integer and Negative Integer - Binary Search [JS]

Count Subarrays With Median K - Count Left & Right Balance [JS]