Open In App

JavaScript Count Distinct Occurrences as a Subsequence

Counting the distinct occurrences is the most common problem in string manipulation. Subsequences are the subsets of the characters in the string which appear in the same order but not necessarily in a consecutive manner. In the problem, the task is to find out the count of how many times a given subsequence appears as a distinct occurrence in the given larger string. In this article, we will explore various approaches to count distinct occurrences as a subsequence

There are different approaches to counting distinct occurrences as a subsequence in JavaScript. Let’s discuss each one of them.



Using Recursion with Memoization

Example: In this example, we will count distinct occurrences as a subsequence using Recursion with Memoization approach




function countSeq(str, seq) {
    const memoTable = new Map();
    function helperFunction(strIdx, seqIdx) {
        if (seqIdx === seq.length) return 1;
        if (strIdx === str.length) return 0;
        const key = strIdx + ',' + seqIdx;
        if (memoTable.has(key)) return memoTable.get(key);
        let count = 0;
        if (str[strIdx] === seq[seqIdx]) {
            count += helperFunction(strIdx + 1, seqIdx + 1);
        }
        count += helperFunction(strIdx + 1, seqIdx);
        memoTable.set(key, count);
        return count;
    }
    return helperFunction(0, 0);
}
  
const str = "geeksforgeeks";
const seq = "ge";
console.log(countSeq(str, seq));

Output

6

Time complexity: O(2 ^ N), where ‘N’ is the length of the input.

Auxiliary space: O(2 ^ N), The space complexity is determined by the space used for the memoTable, which is a Map data structure. Stores for all unique combinations of strIndex and subseqIndex.

Using String Iteration

Example: In this example, we will count distinct occurrences as a subsequence using the String Iteration approach.




function countSeq(str, seq) {
    const m = str.length;
    const n = seq.length;
    const dp = Array(m + 1).fill(0).map(() => Array(n + 1).fill(0));
    for (let i = 0; i <= m; i++) {
        dp[i][0] = 1;
    }
    for (let i = 1; i <= m; i++) {
        for (let j = 1; j <= n; j++) {
            if (str[i - 1] === seq[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
  
    return dp[m][n];
}
const str = "geeksforgeeks";
const pattern = "ge";
console.log(countSeq(str, pattern));

Output
6

Time Complexity: O(M * N), where ‘M’ is the length of the strInput, and ‘N’ is the length of the subseqInput.

Auxiliary space: O(M * N), a two-dimensional array that stores the results of subproblems during dynamic programming.

Using BackTracking

Example: In this example, we will count distinct occurrences as a subsequence using the BackTracking approach.




function fun(str, subSeq) {
    function countSeq(strIndex, subseqIndex) {
        if (subseqIndex === subSeq.length) {
            count++;
            return;
        }
        if (strIndex === str.length) {
            return;
        }
        if (str[strIndex] === subSeq[subseqIndex]) {
            countSeq(strIndex + 1, subseqIndex + 1);
        }
        countSeq(strIndex + 1, subseqIndex);
    }
    let count = 0;
    countSeq(0, 0);
    return count;
}
  
const str = "geeksforgeeks";
const pattern = "ge";
console.log(fun(str, pattern));

Output
6

Time Complexity: O(2^N), where ‘N’ is the lenthgo of ‘strInput’.

Auxiliary space: O(N), where ‘N’ is the lenthgo of ‘strInput’., due to the maximum depth of the recursive call stack, addition to constant space for varibaes and function call oerhead.


Article Tags :