Bird
Raised Fist0
DSA Javascriptprogramming~5 mins

String Pattern Matching Naive in DSA Javascript - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: String Pattern Matching Naive
O(n * m)
Understanding Time Complexity

We want to understand how the time needed to find a pattern in a text grows as the text and pattern get bigger.

How does the number of checks change when the input size increases?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


function naivePatternSearch(text, pattern) {
  const n = text.length;
  const m = pattern.length;
  for (let i = 0; i <= n - m; i++) {
    let j = 0;
    while (j < m && text[i + j] === pattern[j]) {
      j++;
    }
    if (j === m) return i; // pattern found
  }
  return -1; // pattern not found
}
    

This code checks every possible position in the text to see if the pattern matches starting there.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: The nested loops where the outer loop moves through the text and the inner loop compares characters of the pattern to the text.
  • How many times: The outer loop runs about n - m + 1 times, and for each, the inner loop can run up to m times in the worst case.
How Execution Grows With Input

As the text and pattern get longer, the number of character comparisons grows roughly by multiplying their lengths.

Input Size (n)Approx. Operations
10 (text), 3 (pattern)About 8 * 3 = 24 comparisons
100 (text), 5 (pattern)About 96 * 5 = 480 comparisons
1000 (text), 10 (pattern)About 991 * 10 = 9,910 comparisons

Pattern observation: The work grows roughly like the product of text length and pattern length.

Final Time Complexity

Time Complexity: O(n * m)

This means the time needed grows proportionally to the length of the text times the length of the pattern.

Common Mistake

[X] Wrong: "The pattern search always takes time proportional only to the text length (O(n))."

[OK] Correct: Because for each position in the text, the algorithm may check multiple characters of the pattern, so the pattern length also affects the time.

Interview Connect

Understanding this basic search helps build intuition for more efficient algorithms and shows you can analyze nested loops clearly.

Self-Check

"What if we used a more advanced algorithm like KMP? How would the time complexity change compared to this naive approach?"

Practice

(1/5)
1. What does the naive string pattern matching algorithm do?
easy
A. It checks every possible position in the text to find the pattern.
B. It uses a hash function to find the pattern quickly.
C. It sorts the text before searching for the pattern.
D. It uses a tree structure to match the pattern.

Solution

  1. Step 1: Understand naive pattern matching

    The naive algorithm tries to match the pattern starting at every position in the text.
  2. Step 2: Compare with other methods

    Other methods like hashing or trees are not part of the naive approach.
  3. Final Answer:

    It checks every possible position in the text to find the pattern. -> Option A
  4. Quick Check:

    Naive = Check all positions [OK]
Hint: Naive means try all positions one by one [OK]
Common Mistakes:
  • Confusing naive with hashing or advanced algorithms
  • Thinking naive sorts the text
  • Assuming naive uses data structures like trees
2. Which of the following is the correct syntax to start a loop for naive pattern matching in JavaScript?
for (___; i <= text.length - pattern.length; i++)
easy
A. const i = 0
B. var i = 1
C. let i = 0
D. i = 0

Solution

  1. Step 1: Identify loop initialization

    The loop variable must start at 0 to check from the beginning of the text.
  2. Step 2: Choose correct declaration

    Using 'let' is correct for block scope and allows incrementing i.
  3. Final Answer:

    let i = 0 -> Option C
  4. Quick Check:

    Loop start = let i = 0 [OK]
Hint: Use 'let' to declare loop variable starting at zero [OK]
Common Mistakes:
  • Using 'const' which cannot be incremented
  • Starting loop at 1 instead of 0
  • Not declaring variable with let or var
3. What will be the output of the following code?
function naiveSearch(text, pattern) {
  let count = 0;
  for (let i = 0; i <= text.length - pattern.length; i++) {
    let j;
    for (j = 0; j < pattern.length; j++) {
      if (text[i + j] !== pattern[j]) break;
    }
    if (j === pattern.length) count++;
  }
  return count;
}

console.log(naiveSearch('abababa', 'aba'));
medium
A. 3
B. 2
C. 1
D. 0

Solution

  1. Step 1: Check all pattern matches in text

    Positions checked: 0,1,2,3,4. Matches at 0 ('aba'), 2 ('aba'), and 4 ('aba').
  2. Step 2: Count total matches

    There are 3 matches of 'aba' in 'abababa'.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    Count matches = 3 [OK]
Hint: Count overlapping matches carefully [OK]
Common Mistakes:
  • Missing overlapping matches
  • Counting only non-overlapping occurrences
  • Off-by-one errors in loop limits
4. Identify the error in this naive pattern matching code snippet:
function search(text, pattern) {
  for (let i = 0; i < text.length; i++) {
    let j = 0;
    while (j < pattern.length && text[i + j] === pattern[j]) {
      j++;
    }
    if (j === pattern.length) return i;
  }
  return -1;
}
medium
A. j should be declared with var instead of let
B. Loop condition should be i <= text.length - pattern.length
C. Return -1 should be inside the for loop
D. While loop condition should use || instead of &&

Solution

  1. Step 1: Analyze loop range

    The outer loop runs till i < text.length, which can cause out-of-bound access when i + j exceeds text length.
  2. Step 2: Correct loop condition

    It should be i <= text.length - pattern.length to avoid overflow.
  3. Final Answer:

    Loop condition should be i <= text.length - pattern.length -> Option B
  4. Quick Check:

    Loop limit fix = i <= text.length - pattern.length [OK]
Hint: Limit loop to avoid index overflow [OK]
Common Mistakes:
  • Ignoring index overflow causing runtime errors
  • Misplacing return statements
  • Wrong logical operators in conditions
5. Given a text and a pattern, how can you modify the naive pattern matching algorithm to count only non-overlapping occurrences of the pattern in the text?
hard
A. Use recursion to find matches
B. Use a hash function to skip characters
C. Sort the text before searching
D. After finding a match, increment the outer loop index by pattern length instead of 1

Solution

  1. Step 1: Understand overlapping vs non-overlapping

    Naive checks every position, counting overlapping matches. To avoid overlap, skip ahead after a match.
  2. Step 2: Modify loop increment

    When a match is found, increase the index by pattern length to jump past the matched substring.
  3. Final Answer:

    After finding a match, increment the outer loop index by pattern length instead of 1 -> Option D
  4. Quick Check:

    Skip matched length to avoid overlap [OK]
Hint: Jump by pattern length after match to avoid overlaps [OK]
Common Mistakes:
  • Trying to sort text which doesn't help
  • Using hashing which is unrelated here
  • Recursion adds complexity without solving overlap
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