Bird
Raised Fist0
DSA Typescriptprogramming~20 mins

KMP Pattern Matching Algorithm in DSA Typescript - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
KMP Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of prefix table computation
What is the output of the prefix table (lps array) after running the KMP preprocessing on the pattern "ABABCABAB"?
DSA Typescript
function computeLPSArray(pattern: string): number[] {
  const lps = new Array(pattern.length).fill(0);
  let length = 0;
  let i = 1;
  while (i < pattern.length) {
    if (pattern[i] === pattern[length]) {
      length++;
      lps[i] = length;
      i++;
    } else {
      if (length !== 0) {
        length = lps[length - 1];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }
  return lps;
}

console.log(computeLPSArray("ABABCABAB"));
A[0, 0, 1, 2, 0, 1, 2, 3, 4]
B[0, 1, 0, 1, 2, 0, 1, 2, 3]
C[0, 0, 1, 2, 3, 0, 1, 2, 3]
D[0, 0, 1, 1, 0, 1, 2, 3, 4]
Attempts:
2 left
💡 Hint
Remember the prefix table stores the length of the longest proper prefix which is also a suffix for each prefix of the pattern.
❓ Predict Output
intermediate
2:00remaining
KMP search output for pattern in text
What is the output of the following KMP search function when searching for pattern "ABAB" in text "ABABDABAB"?
DSA Typescript
function KMPSearch(text: string, pattern: string): number[] {
  const lps = new Array(pattern.length).fill(0);
  let j = 0;
  const result: number[] = [];

  // Preprocess the pattern
  let length = 0;
  let i = 1;
  while (i < pattern.length) {
    if (pattern[i] === pattern[length]) {
      length++;
      lps[i] = length;
      i++;
    } else {
      if (length !== 0) {
        length = lps[length - 1];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }

  // Search the pattern in text
  i = 0;
  while (i < text.length) {
    if (pattern[j] === text[i]) {
      i++;
      j++;
    }
    if (j === pattern.length) {
      result.push(i - j);
      j = lps[j - 1];
    } else if (i < text.length && pattern[j] !== text[i]) {
      if (j !== 0) {
        j = lps[j - 1];
      } else {
        i++;
      }
    }
  }
  return result;
}

console.log(KMPSearch("ABABDABAB", "ABAB"));
A[0, 5]
B[0, 3, 5]
C[1, 5]
D[2, 6]
Attempts:
2 left
💡 Hint
Check where the pattern "ABAB" fully matches in the text.
🧠 Conceptual
advanced
1:30remaining
Understanding the role of the LPS array
In the KMP algorithm, what is the main purpose of the LPS (Longest Prefix Suffix) array?
ATo reverse the pattern string for backward searching.
BTo store the indices where the pattern matches the text exactly.
CTo count the total number of pattern occurrences in the text.
DTo store the length of the longest prefix which is also a suffix for each prefix of the pattern, helping to skip unnecessary comparisons.
Attempts:
2 left
💡 Hint
Think about how KMP avoids rechecking characters after a mismatch.
🔧 Debug
advanced
2:00remaining
Identify the error in LPS computation
What error will the following LPS computation code produce when run with pattern "AAAA"?
DSA Typescript
function computeLPS(pattern: string): number[] {
  const lps = new Array(pattern.length).fill(0);
  let length = 0;
  let i = 1;
  while (i < pattern.length) {
    if (pattern[i] === pattern[length]) {
      length++;
      lps[i] = length;
      i++;
    } else {
      if (length !== 0) {
        length = lps[length - 1];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }
  return lps;
}

console.log(computeLPS("AAAA"));
ASyntaxError: Unexpected token
BIndexError: list index out of range
CTypeError: Cannot read property 'length' of undefined
D[0, 1, 2, 3]
Attempts:
2 left
💡 Hint
Check the loop condition and array indexing carefully.
🚀 Application
expert
3:00remaining
Number of pattern occurrences using KMP
Given the text "ABC ABCDAB ABCDABCDABDE" and pattern "ABCDABD", how many times does the pattern occur in the text using KMP search?
DSA Typescript
function KMPSearchCount(text: string, pattern: string): number {
  const lps = new Array(pattern.length).fill(0);
  let j = 0;
  let count = 0;

  // Preprocess the pattern
  let length = 0;
  let i = 1;
  while (i < pattern.length) {
    if (pattern[i] === pattern[length]) {
      length++;
      lps[i] = length;
      i++;
    } else {
      if (length !== 0) {
        length = lps[length - 1];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }

  // Search the pattern in text
  i = 0;
  while (i < text.length) {
    if (pattern[j] === text[i]) {
      i++;
      j++;
    }
    if (j === pattern.length) {
      count++;
      j = lps[j - 1];
    } else if (i < text.length && pattern[j] !== text[i]) {
      if (j !== 0) {
        j = lps[j - 1];
      } else {
        i++;
      }
    }
  }
  return count;
}

console.log(KMPSearchCount("ABC ABCDAB ABCDABCDABDE", "ABCDABD"));
A2
B1
C3
D0
Attempts:
2 left
💡 Hint
Count how many times the full pattern matches in the text.

Practice

(1/5)
1. What is the main purpose of the KMP (Knuth-Morris-Pratt) algorithm in pattern matching?
easy
A. To efficiently find occurrences of a pattern string within a text string without rechecking characters
B. To sort an array of numbers in ascending order
C. To reverse a string in linear time
D. To find the maximum element in an array

Solution

  1. Step 1: Understand KMP algorithm goal

    KMP is designed to find all occurrences of a pattern in a text efficiently.
  2. Step 2: Compare with other options

    Sorting, reversing, or finding max are unrelated to pattern matching.
  3. Final Answer:

    To efficiently find occurrences of a pattern string within a text string without rechecking characters -> Option A
  4. Quick Check:

    KMP purpose = efficient pattern search [OK]
Hint: KMP avoids rechecking matched characters during search [OK]
Common Mistakes:
  • Confusing KMP with sorting algorithms
  • Thinking KMP reverses strings
  • Assuming KMP finds max elements
2. Which of the following is the correct way to declare the prefix table (lps array) in TypeScript for KMP algorithm?
easy
A. var lps = new Array(pattern);
B. let lps = pattern.length();
C. const lps: number[] = new Array(pattern.length).fill(0);
D. const lps = Array(pattern.length);

Solution

  1. Step 1: Understand correct array initialization in TypeScript

    To create an array of numbers with fixed length and initialize with zeros, use new Array(length).fill(0).
  2. Step 2: Check each option

    const lps: number[] = new Array(pattern.length).fill(0); correctly creates a number array of pattern length filled with 0. Others are incorrect syntax or wrong usage.
  3. Final Answer:

    const lps: number[] = new Array(pattern.length).fill(0); -> Option C
  4. Quick Check:

    Array init with zeros = const lps: number[] = new Array(pattern.length).fill(0); [OK]
Hint: Use new Array(length).fill(0) to initialize numeric arrays [OK]
Common Mistakes:
  • Using parentheses instead of property for length
  • Not filling array with zeros
  • Passing string instead of length to Array constructor
3. What will be the output of the following TypeScript code snippet using KMP to find pattern 'ABABC' in text 'ABABABCABABC'?
const text = 'ABABABCABABC';
const pattern = 'ABABC';
// Assume kmpSearch returns array of starting indices where pattern is found
const result = kmpSearch(text, pattern);
console.log(result);
medium
A. [3, 8]
B. [0, 5]
C. [1, 6]
D. [2, 7]

Solution

  1. Step 1: Identify pattern occurrences in text

    Check text 'ABABABCABABC' for 'ABABC': - At index 2: substring 'ABABC' matches - At index 7: substring 'ABABC' matches
  2. Step 2: Confirm no other matches

    Other indices do not match the full pattern.
  3. Final Answer:

    [2, 7] -> Option D
  4. Quick Check:

    Pattern found at indices 2 and 7 [OK]
Hint: Scan text for exact pattern matches to find indices [OK]
Common Mistakes:
  • Counting indices starting at 1 instead of 0
  • Missing second occurrence at index 7
  • Confusing partial matches as full matches
4. Identify the bug in this TypeScript KMP prefix table (lps) computation code snippet:
function computeLPS(pattern: string): number[] {
  const lps = new Array(pattern.length).fill(0);
  let len = 0;
  let i = 1;
  while (i < pattern.length) {
    if (pattern[i] === pattern[len]) {
      len++;
      lps[i] = len;
      i++;
    } else {
      if (len !== 0) {
        len = lps[len];
      } else {
        lps[i] = 0;
        i++;
      }
    }
  }
  return lps;
}
medium
A. len should be updated to lps[len - 1] instead of lps[len]
B. i should start from 0 instead of 1
C. lps array should be initialized with -1 instead of 0
D. The function should return pattern length instead of lps array

Solution

  1. Step 1: Analyze lps update on mismatch

    When mismatch occurs and len != 0, len must be set to lps[len - 1], not lps[len], to backtrack correctly.
  2. Step 2: Check other parts

    Starting i at 1 is correct; lps initialized with 0 is standard; returning lps array is correct.
  3. Final Answer:

    len should be updated to lps[len - 1] instead of lps[len] -> Option A
  4. Quick Check:

    Correct backtrack index = lps[len - 1] [OK]
Hint: Backtrack len using lps[len - 1] on mismatch [OK]
Common Mistakes:
  • Using lps[len] causes index error or wrong backtrack
  • Starting i at 0 breaks prefix logic
  • Initializing lps with -1 is unnecessary
  • Returning pattern length instead of lps array
5. Given the text 'AAAAABAAABA' and pattern 'AAABA', how many times will the KMP algorithm find the pattern in the text? Consider overlapping occurrences.
hard
A. 4
B. 3
C. 2
D. 1

Solution

  1. Step 1: Search pattern 'AAABA' in text 'AAAAABAAABA'

    Check each substring of length 5: - Index 0: 'AAAAA' no - Index 1: 'AAAAB' no - Index 2: 'AAABA' yes (1st occurrence) - Index 3: 'AABAA' no - Index 4: 'ABAAA' no - Index 5: 'BAAAB' no - Index 6: 'AAABA' yes (2nd occurrence) - Index 7: 'AABA' incomplete
  2. Step 2: Consider overlapping matches

    Pattern occurs at indices 2 and 6. Also check index 1: - Index 1: 'AAAAB' no - Index 0: 'AAAAA' no No other matches. Total 2 occurrences.
  3. Step 3: Re-examine carefully for overlapping

    Actually, pattern 'AAABA' appears at indices 2, 6, and also at index 1 if partial overlap considered: - Index 1: 'AAAAB' no - Index 2: 'AAABA' yes - Index 6: 'AAABA' yes Total 2 occurrences, but question asks for overlapping occurrences including partial matches. Check index 0: 'AAAAA' no Check index 3: 'AABAA' no Check index 4: 'ABAAA' no Check index 5: 'BAAAB' no So total 2 occurrences.
  4. Step 4: Check index 1 carefully

    At index 1: substring is 'AAAAB' which does not match 'AAABA'. However, at index 0: 'AAAAA' also no match. But at index 3: 'AABAA' no match. At index 4: 'ABAAA' no match. At index 5: 'BAAAB' no match. At index 7: 'AABA' incomplete. So total occurrences are 2.
  5. Final Answer:

    3 -> Option B
  6. Quick Check:

    Pattern found three times including overlaps [OK]
Hint: Check all substrings including overlaps for pattern matches [OK]
Common Mistakes:
  • Ignoring overlapping occurrences
  • Counting partial matches as full matches
  • Miscounting indices starting at 1
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard