Open In App

Find the number of Substrings with even number of K

Last Updated : 18 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string str of length N and an integer K, the task is to count the number of substrings with even numbers of K. It means the count of ‘K’ in each substring will be even and must not be zero.

Examples:

Input: N = 4, str = “2131”, K = 1
Output: 2 
Explanation: There are two substrings “2131” and ‘131″ having an even number of  K.

Input: N = 4, str = “1121”, K = 2
Output: 0
Explanation: No, substring exists having an even number of K.

Approach: This can be solved with the following idea:

We can precompute an array that counts the occurrence of K. After computing this we can traverse the for loops two times to find the ranges and checking the occurrence between the range is odd or even. For more clarity follow the process.

Below are the steps of implementation:

  • Declare a new array oneoccur[] of the same size as the input string.
  • Run a for loop to traverse the input string.
    • For each index add the value of the previous value of the precomputing array if the element is other than K and if the current element is K add the previous element incremented by 1.
  • Now we have all occurrences of K till all indexes.
  • Now we have to find all the ranges possible. For that traverse a nested for loop.
  • In each range find the number of occurring K in this range.
  • Check whether the number is even or not and check if it is not equal to 0.
  • If it is even and not equal to zero, then increment the counter variable.
  • After traversing all possible ranges Output the cnt.

Below is the implementation of the above approach:

C++




// C++ code of the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// To compute occurrence of K
void oneoccur(string arr, int n, int prefixSum[], char K)
{
 
    // Initialize
    if (arr[0] == K) {
        prefixSum[0] = 1;
    }
    else {
        prefixSum[0] = 0;
    }
 
    for (int i = 1; i < n; i++)
 
    {
 
        // Adding previous element
        // incremented by 1
        if (arr[i] == K)
            prefixSum[i] = prefixSum[i - 1] + 1;
 
        // Adding  previous element
        else
            prefixSum[i] = prefixSum[i - 1];
    }
}
 
// Function to find count
// number of substrings
void findevenone(string s, int n, char K)
{
 
    // Precomputing onecnt[] array
    int onencnt[n];
 
    // Precomputing the occurrence
    // of K in onecnt[]
    oneoccur(s, n, onencnt, K);
 
    // Counter variable
    int cnt = 0;
 
    // For loop for traversing all the
    // rages for possible subarray
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
 
            int onecnt = 0;
 
            // Counting the occurrence of
            // '1' occurrence of '1' from
            // i to j is pre[j]-pre[i-1]
            // if i==0 then this is pre[j]
            if (i == 0) {
                if (onencnt[j] % 2 == 0
                    && onencnt[j] != 0) {
 
                    // Incrementing count
                    cnt++;
                }
            }
            else {
                if ((onencnt[j] - onencnt[i - 1]) % 2 == 0
                    && (onencnt[j] - onencnt[i - 1]) != 0) {
 
                    // Incrementing count
                    cnt++;
                }
            }
        }
    }
 
    // Output it
    cout << cnt << endl;
 
    return;
}
 
// Driver code
int main()
{
    string str = "2131";
    char K = '1';
    int size = str.size();
 
    // Function call
    findevenone(str, size, K);
 
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
    // To compute occurrence of K
    static void oneoccur(String arr, int n, int prefixSum[], char K) {
        // Initialize
        if (arr.charAt(0) == K) {
            prefixSum[0] = 1;
        } else {
            prefixSum[0] = 0;
        }
 
        for (int i = 1; i < n; i++) {
            // Adding previous element incremented by 1
            if (arr.charAt(i) == K) {
                prefixSum[i] = prefixSum[i - 1] + 1;
            } else {
                prefixSum[i] = prefixSum[i - 1];
            }
        }
    }
 
    // Function to find count of number of substrings
    static void findevenone(String s, int n, char K) {
        // Precomputing onecnt[] array
        int onencnt[] = new int[n];
 
        // Precomputing the occurrence of K in onecnt[]
        oneoccur(s, n, onencnt, K);
 
        // Counter variable
        int cnt = 0;
 
        // For loop for traversing all the ranges for possible subarray
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                int onecnt = 0;
 
                // Counting the occurrence of '1' from i to j
                // The occurrence of '1' from i to j is pre[j]-pre[i-1]
                // if i==0 then this is pre[j]
                if (i == 0) {
                    if (onencnt[j] % 2 == 0 && onencnt[j] != 0) {
                        // Incrementing count
                        cnt++;
                    }
                } else {
                    if ((onencnt[j] - onencnt[i - 1]) % 2 == 0 && (onencnt[j] - onencnt[i - 1]) != 0) {
                        // Incrementing count
                        cnt++;
                    }
                }
            }
        }
 
        // Output it
        System.out.println(cnt);
    }
 
    // Driver code
    public static void main(String[] args) {
        String str = "2131";
        char K = '1';
        int size = str.length();
 
        // Function call
        findevenone(str, size, K);
    }
}


Python3




# Python code of the above approach
 
# To compute occurrence of K
def oneoccur(arr, n, prefixSum, K):
    # Initialize
    if arr[0] == K:
        prefixSum[0] = 1
    else:
        prefixSum[0] = 0
 
    for i in range(1, n):
       
        # Adding previous element incremented by 1
        if arr[i] == K:
            prefixSum[i] = prefixSum[i - 1] + 1
             
        # Adding previous element
        else:
            prefixSum[i] = prefixSum[i - 1]
 
# Function to find count number of substrings
def findevenone(s, n, K):
   
    # Precomputing onecnt[] array
    onecnt = [0] * n
 
    # Precomputing the occurrence of K in onecnt[]
    oneoccur(s, n, onecnt, K)
 
    # Counter variable
    cnt = 0
 
    # For loop for traversing all the ranges for possible subarray
    for i in range(n):
        for j in range(i, n):
           
            # Counting the occurrence of '1' from i to j is pre[j]-pre[i-1]
            # if i==0 then this is pre[j]
            if i == 0:
                if onecnt[j] % 2 == 0 and onecnt[j] != 0:
                   
                    # Incrementing count
                    cnt += 1
            else:
                if (onecnt[j] - onecnt[i - 1]) % 2 == 0 and (onecnt[j] - onecnt[i - 1]) != 0:
                    # Incrementing count
                    cnt += 1
 
    # Output it
    print(cnt)
 
# Driver code
if __name__ == '__main__':
    str = "2131"
    K = '1'
    size = len(str)
 
    # Function call
    findevenone(str, size, K)
 
# This code is contributed by Susobhan Akhuli


C#




using System;
 
class Program {
    // To compute occurrence of K
    static void OneOccur(string arr, int n, int[] prefixSum,
                         char K)
    {
        // Initialize
        if (arr[0] == K) {
            prefixSum[0] = 1;
        }
        else {
            prefixSum[0] = 0;
        }
 
        for (int i = 1; i < n; i++) {
            // Adding previous element incremented by 1
            if (arr[i] == K)
                prefixSum[i] = prefixSum[i - 1] + 1;
 
            // Adding previous element
            else
                prefixSum[i] = prefixSum[i - 1];
        }
    }
 
    // Function to find count of number of substrings
    static void FindEvenOne(string s, int n, char K)
    {
        // Precomputing onecnt[] array
        int[] oneCnt = new int[n];
 
        // Precomputing the occurrence of K in onecnt[]
        OneOccur(s, n, oneCnt, K);
 
        // Counter variable
        int cnt = 0;
 
        // For loop for traversing all the ranges for
        // possible subarray
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                int oneCntInRange = 0;
 
                // Counting the occurrence of '1'
                // Occurrence of '1' from i to j is
                // oneCnt[j] - oneCnt[i - 1] If i == 0 then
                // this is oneCnt[j]
                if (i == 0) {
                    if (oneCnt[j] % 2 == 0
                        && oneCnt[j] != 0) {
                        // Incrementing count
                        cnt++;
                    }
                }
                else {
                    if ((oneCnt[j] - oneCnt[i - 1]) % 2 == 0
                        && (oneCnt[j] - oneCnt[i - 1])
                               != 0) {
                        // Incrementing count
                        cnt++;
                    }
                }
            }
        }
 
        // Output it
        Console.WriteLine(cnt);
    }
 
    // Driver code
    static void Main()
    {
        string str = "2131";
        char K = '1';
        int size = str.Length;
 
        // Function call
        FindEvenOne(str, size, K);
    }
}


Javascript




// JS code of the above approach:
 
// To compute occurrence of K
function oneoccur( arr,  n,  prefixSum,  K)
{
 
    // Initialize
    if (arr[0] == K) {
        prefixSum[0] = 1;
    }
    else {
        prefixSum[0] = 0;
    }
 
    for (let i = 1; i < n; i++)
    {
 
        // Adding previous element
        // incremented by 1
        if (arr[i] == K)
            prefixSum[i] = prefixSum[i - 1] + 1;
 
        // Adding  previous element
        else
            prefixSum[i] = prefixSum[i - 1];
    }
}
 
// Function to find count
// number of substrings
function findevenone( s,  n,  K)
{
 
    // Precomputing onecnt[] array
    let onencnt=new Array(n);
 
    // Precomputing the occurrence
    // of K in onecnt[]
    oneoccur(s, n, onencnt, K);
 
    // Counter variable
    let cnt = 0;
 
    // For loop for traversing all the
    // rages for possible subarray
    for (let i = 0; i < n; i++) {
        for (let j = i; j < n; j++) {
 
            let onecnt = 0;
 
            // Counting the occurrence of
            // '1' occurrence of '1' from
            // i to j is pre[j]-pre[i-1]
            // if i==0 then this is pre[j]
            if (i == 0) {
                if (onencnt[j] % 2 == 0
                    && onencnt[j] != 0) {
 
                    // Incrementing count
                    cnt++;
                }
            }
            else {
                if ((onencnt[j] - onencnt[i - 1]) % 2 == 0
                    && (onencnt[j] - onencnt[i - 1]) != 0) {
 
                    // Incrementing count
                    cnt++;
                }
            }
        }
    }
 
    // Output it
    console.log(cnt);
 
    return;
}
 
// Driver code
let str = "2131";
let K = '1';
let size = str.length;
 
// Function call
findevenone(str, size, K);


Output

2

Time complexity: O(N2)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads