Frequency of a Substring in a String

Last Updated : 2 Jul, 2026

Given two strings s1 and s2, consisting of lowercase English letters, find the number of occurrences of s2 as a substring in s1. Overlapping occurrences should also be counted.

Examples: 

Input: s1 = "gfggfg", s2 = "gfg"
Output: 2
Explanation: s2 occurs twice in s1. Once starting at index 0 and once starting at index 3 .

Input: s1 = "banana", s2 = "nn"
Output: 0
Explanation: s2 does not occur in s1.

Input: s1 = "aaaaa", s2 = "aa"
Output: 4
Explanation: s2 occurs at indices 0, 1, 2, and 3 in s1. Overlapping occurrences are also counted.

Try It Yourself
redirect icon

[Naive Approach] Nested Loop Substring Comparison - O(|s1|*|s2|) Time and O(1) Space

Check every starting index in s1 as a possible match for s2, comparing characters one by one. The starting index always moves forward by just one position, whether or not a match was found, so overlapping occurrences are counted correctly.

Step by Step Implementation:

  • Let n be the length of s1 and m be the length of s2.
  • Iterate the starting index i from 0 to n - m (inclusive), since s2 cannot fit starting any later than that.
  • At each i, compare s1[i], s1[i+1], ..., s1[i+m-1] against s2[0], s2[1], ..., s2[m-1] character by character.
  • If every character matches, increment the count.
  • Move to the next starting index and repeat, so overlapping matches are also counted.
  • Return the final count.
C++
#include <iostream>
#include <string>

using namespace std;

// function to count occurrences of s2 in s1 using nested loop comparison
int countFreq(string s1, string s2) {

    int n = s1.size();
    int m = s2.size();
    int count = 0;

    // try every possible starting index in s1
    for (int i = 0; i <= n - m; i++) {
        int j = 0;

        // compare characters of s2 with s1 starting at index i
        while (j < m && s1[i + j] == s2[j]) {
            j++;
        }

        // if all characters matched, count this occurrence
        if (j == m) {
            count++;
        }
    }

    return count;
}

int main() {

    string s1 = "gfggfg";
    string s2 = "gfg";

    cout << countFreq(s1, s2) << endl;

    return 0;
}
Java
class GFG {

    // function to count occurrences of s2 in s1 using nested loop comparison
    static int countFreq(String s1, String s2) {

        int n = s1.length();
        int m = s2.length();
        int count = 0;

        // try every possible starting index in s1
        for (int i = 0; i <= n - m; i++) {
            int j = 0;

            // compare characters of s2 with s1 starting at index i
            while (j < m && s1.charAt(i + j) == s2.charAt(j)) {
                j++;
            }

            // if all characters matched, count this occurrence
            if (j == m) {
                count++;
            }
        }

        return count;
    }

    public static void main(String[] args) {

        String s1 = "gfggfg";
        String s2 = "gfg";

        System.out.println(countFreq(s1, s2));
    }
}
Python
# function to count occurrences of s2 in s1 using nested loop comparison
def countFreq(s1, s2):

    n = len(s1)
    m = len(s2)
    count = 0

    # try every possible starting index in s1
    for i in range(n - m + 1):
        j = 0

        # compare characters of s2 with s1 starting at index i
        while j < m and s1[i + j] == s2[j]:
            j += 1

        # if all characters matched, count this occurrence
        if j == m:
            count += 1

    return count

if __name__ == "__main__":

    s1 = "gfggfg"
    s2 = "gfg"

    print(countFreq(s1, s2))
C#
using System;

class GFG {

    // function to count occurrences of s2 in s1 using nested loop comparison
    static int countFreq(string s1, string s2) {

        int n = s1.Length;
        int m = s2.Length;
        int count = 0;

        // try every possible starting index in s1
        for (int i = 0; i <= n - m; i++) {
            int j = 0;

            // compare characters of s2 with s1 starting at index i
            while (j < m && s1[i + j] == s2[j]) {
                j++;
            }

            // if all characters matched, count this occurrence
            if (j == m) {
                count++;
            }
        }

        return count;
    }

    static void Main(string[] args) {

        string s1 = "gfggfg";
        string s2 = "gfg";

        Console.WriteLine(countFreq(s1, s2));
    }
}
JavaScript
// function to count occurrences of s2 in s1 using nested loop comparison
function countFreq(s1, s2) {

    let n = s1.length;
    let m = s2.length;
    let count = 0;

    // try every possible starting index in s1
    for (let i = 0; i <= n - m; i++) {
        let j = 0;

        // compare characters of s2 with s1 starting at index i
        while (j < m && s1[i + j] === s2[j]) {
            j++;
        }

        // if all characters matched, count this occurrence
        if (j === m) {
            count++;
        }
    }

    return count;
}

// Driver Code
let s1 = "gfggfg";
let s2 = "gfg";

console.log(countFreq(s1, s2));

Output
2

[Expected Approach] Using KMP Algorithm - O(|s1| + |s2|) Time and O(|s2|) Space

Preprocess s2 into an LPS array using the KMP algorithm, storing for every prefix of s2 the length of its longest proper prefix that is also a suffix. This lets a mismatch fall back to a partially matched state instead of restarting from scratch, and on a full match, falling back the same way (instead of resetting to 0) lets overlapping occurrences be counted too.

Step by Step Implementation:

  • Build the LPS array for s2: for each index, extend the match length if characters agree, or fall back using the LPS array itself if they don't.
  • Scan s1 with a pointer j tracking how much of s2 has matched so far.
  • On a mismatch, fall back j using the LPS array instead of restarting from index 0.
  • On a match, advance j. If j reaches |s2|, count the occurrence and fall back j using the LPS array to continue checking for overlaps.
  • Return the count once s1 is fully scanned.
C++
#include <iostream>
#include <string>
#include <vector>

using namespace std;

// function to count occurrences of s2 in s1 using kmp algorithm
int countFreq(string s1, string s2) {

    int m = s2.size();

    // build the lps array for s2
    vector<int> lps(m, 0);
    int length = 0;

    for (int i = 1; i < m; i++) {
        while (length > 0 && s2[i] != s2[length]) {
            length = lps[length - 1];
        }
        if (s2[i] == s2[length]) {
            length++;
        }
        lps[i] = length;
    }

    // use the lps array to count all overlapping occurrences of s2 in s1
    int n = s1.size();
    int count = 0;
    int j = 0;

    for (int i = 0; i < n; i++) {
        while (j > 0 && s1[i] != s2[j]) {
            j = lps[j - 1];
        }
        if (s1[i] == s2[j]) {
            j++;
        }
        if (j == m) {

            // full match found, count it and continue searching for overlaps
            count++;
            j = lps[j - 1];
        }
    }

    return count;
}

int main() {

    string s1 = "gfggfg";
    string s2 = "gfg";

    cout << countFreq(s1, s2) << endl;

    return 0;
}
Java
class GFG {

    // function to count occurrences of s2 in s1 using kmp algorithm
    static int countFreq(String s1, String s2) {

        int m = s2.length();

        // build the lps array for s2
        int[] lps = new int[m];
        int length = 0;

        for (int i = 1; i < m; i++) {
            while (length > 0 && s2.charAt(i) != s2.charAt(length)) {
                length = lps[length - 1];
            }
            if (s2.charAt(i) == s2.charAt(length)) {
                length++;
            }
            lps[i] = length;
        }

        // use the lps array to count all overlapping occurrences of s2 in s1
        int n = s1.length();
        int count = 0;
        int j = 0;

        for (int i = 0; i < n; i++) {
            while (j > 0 && s1.charAt(i) != s2.charAt(j)) {
                j = lps[j - 1];
            }
            if (s1.charAt(i) == s2.charAt(j)) {
                j++;
            }
            if (j == m) {

                // full match found, count it and continue searching for overlaps
                count++;
                j = lps[j - 1];
            }
        }

        return count;
    }

    public static void main(String[] args) {

        String s1 = "gfggfg";
        String s2 = "gfg";

        System.out.println(countFreq(s1, s2));
    }
}
Python
# function to count occurrences of s2 in s1 using kmp algorithm
def countFreq(s1, s2):

    m = len(s2)

    # build the lps array for s2
    lps = [0] * m
    length = 0

    for i in range(1, m):
        while length > 0 and s2[i] != s2[length]:
            length = lps[length - 1]
        if s2[i] == s2[length]:
            length += 1
        lps[i] = length

    # use the lps array to count all overlapping occurrences of s2 in s1
    n = len(s1)
    count = 0
    j = 0

    for i in range(n):
        while j > 0 and s1[i] != s2[j]:
            j = lps[j - 1]
        if s1[i] == s2[j]:
            j += 1
        if j == m:

            # full match found, count it and continue searching for overlaps
            count += 1
            j = lps[j - 1]

    return count

if __name__ == "__main__":

    s1 = "gfggfg"
    s2 = "gfg"

    print(countFreq(s1, s2))
C#
using System;

class GFG {

    // function to count occurrences of s2 in s1 using kmp algorithm
    static int countFreq(string s1, string s2) {

        int m = s2.Length;

        // build the lps array for s2
        int[] lps = new int[m];
        int length = 0;

        for (int i = 1; i < m; i++) {
            while (length > 0 && s2[i] != s2[length]) {
                length = lps[length - 1];
            }
            if (s2[i] == s2[length]) {
                length++;
            }
            lps[i] = length;
        }

        // use the lps array to count all overlapping occurrences of s2 in s1
        int n = s1.Length;
        int count = 0;
        int j = 0;

        for (int i = 0; i < n; i++) {
            while (j > 0 && s1[i] != s2[j]) {
                j = lps[j - 1];
            }
            if (s1[i] == s2[j]) {
                j++;
            }
            if (j == m) {

                // full match found, count it and continue searching for overlaps
                count++;
                j = lps[j - 1];
            }
        }

        return count;
    }

    static void Main(string[] args) {

        string s1 = "gfggfg";
        string s2 = "gfg";

        Console.WriteLine(countFreq(s1, s2));
    }
}
JavaScript
// function to count occurrences of s2 in s1 using kmp algorithm
function countFreq(s1, s2) {

    let m = s2.length;

    // build the lps array for s2
    let lps = new Array(m).fill(0);
    let length = 0;

    for (let i = 1; i < m; i++) {
        while (length > 0 && s2[i] !== s2[length]) {
            length = lps[length - 1];
        }
        if (s2[i] === s2[length]) {
            length++;
        }
        lps[i] = length;
    }

    // use the lps array to count all overlapping occurrences of s2 in s1
    let n = s1.length;
    let count = 0;
    let j = 0;

    for (let i = 0; i < n; i++) {
        while (j > 0 && s1[i] !== s2[j]) {
            j = lps[j - 1];
        }
        if (s1[i] === s2[j]) {
            j++;
        }
        if (j === m) {

            // full match found, count it and continue searching for overlaps
            count++;
            j = lps[j - 1];
        }
    }

    return count;
}

// Driver Code
let s1 = "gfggfg";
let s2 = "gfg";

console.log(countFreq(s1, s2));

Output
2
Comment