Open In App

Count odd length Substrings with median same as Kth character of String

Last Updated : 21 Oct, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S of size N, the task is to find the number of substrings of odd lengths that have a median equal to the Kth character of the string.

Examples:

Input: S = “ecadgg”, K = 4
Output: 4
Explanation: Character at 4th position in string is ‘d’. 
Then there are 4 odd length substrings with ‘d’ as their median: 
[d], [a, d, g], [e, c, a, d, g], therefore return 4 as the answer.

Input: s = “abc”, K = 1
Output: 1
Explanation: Character at 1st position in string is ‘a’. Then there is only 1 odd length substring with ‘a’ as its median: [a] therefore return 1 as the answer.

Approach: To solve the problem follow the below idea:

Median is middle element. So smaller elements has to be equal to number of bigger elements, the desired substrings would be like (S[K]) or (2 elements on left and right), (4 elements on left and right), so on. . . [cannot take 1, 3 . . . because the substring should have odd length]

  • We can maintain smaller and bigger arrays of length N and populate them.
  • This helps us to find in range [i, j] count of smaller and bigger elements with respect to S[K]. 
    • For S[K] to be median in the range [i, j], the number of characters smaller than S[K] should be equal to the number of characters greater than S[K] and the subarray should include S[K].

Note: We are considering 1based indexing of string for understanding but the actual implementation uses 0 based indexing.

Follow the steps to solve the problem:

  • Create two vectors namely greater and smaller of size N.
  • Traverse the string: 
    • Mark 1 in a smaller vector at ith position, if the character at that index is smaller than the Kth character of the string, and 
    • Mark 1 in a greater vector at the ith position if the character is greater than the Kth character of the string.
  • Create a difference array that stores the difference of smaller and greater for each ith position.
  • Use prefix sum on difference array to find valid subarrays. In valid subarrays, the sum will be 0.
    • Use the prefix sum for the following three segments:
      • start = 0 and end = N and store it in val1,  
      • start = 0 and end = K-1 store it in val2 and 
      • start = K and end = N and store it in val3.
  • In the end, return val1 – val2 – val3, which is the count of substrings with equally smaller and greater elements that contain Kth character.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function for finding the number of
// sub strings in (start, end) where
// sum of difference is zero
int sum(int start, int end, vector<int>& v)
{
    // STL map to store number of subarrays
    // starting from index zero having
    // particular value of sum.
    unordered_map<int, int> prevSum;
 
    int res = 0, currSum = 0;
 
    for (int i = start; i < end; i++) {
 
        // Add current element to sum so far.
        currSum += v[i];
 
        // If currsum is equal to 0, then
        // a new subarray is found.
        // So increase count of subarrays.
        if (currSum == 0)
            res++;
 
        if (prevSum.find(currSum) != prevSum.end())
            res += (prevSum[currSum]);
 
        // Add currsum value to count of
        // different values of sum.
        prevSum[currSum]++;
    }
 
    return res;
}
 
// Function to find odd length substrings
// whose median is equal to s[k-1]
int numberOfSubstrings(string& s, int k)
{
    int n = s.size();
 
    // Initializing vectors for storing
    // element is smaller or greater
    // than median
    vector<int> smaller(n, 0), greater(n, 0);
    for (int i = 0; i < n; i++) {
        smaller[i] = s[i] < s[k - 1];
 
        greater[i] = s[i] > s[k - 1];
    }
 
    // Declaring a vector to store
    // difference of greater and smaller
    // characters for each position
    vector<int> diff(n, 0);
    for (int i = 0; i < n; i++)
        diff[i] = smaller[i] - greater[i];
 
    // Substrings in (0 to n)
    int val1 = sum(0, n, diff);
 
    // Substrings  in (0 to k-1)
    int val2 = sum(0, k - 1, diff);
 
    // Substrings in (k to n)
    int val3 = sum(k, n, diff);
 
    // Considering only those sub strings
    // with difference 0 that
    // contains s[k-1]
    return val1 - val2 - val3;
}
 
// Driver code
int main()
{
    string S = "ecadgg";
    int K = 4;
 
    // Function call
    cout << numberOfSubstrings(S, K);
 
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG {
    // Function for finding the number of
    // sub strings in (start, end) where
    // sum of difference is zero
    public static int sum(int start, int end, int v[])
    {
        // STL map to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        HashMap<Integer, Integer> prevSum
            = new HashMap<Integer, Integer>();
 
        int res = 0, currSum = 0;
 
        for (int i = start; i < end; i++) {
 
            // Add current element to sum so far.
            currSum += v[i];
 
            // If currsum is equal to 0, then
            // a new subarray is found.
            // So increase count of subarrays.
            if (currSum == 0)
                res++;
 
            if (prevSum.containsKey(currSum)) {
                res += prevSum.get(currSum);
                prevSum.put(currSum,
                            prevSum.get(currSum) + 1);
            }
            // Add currsum value to count of
            // different values of sum.
            prevSum.put(currSum, 1);
        }
 
        return res;
    }
 
    // Function to find odd length substrings
    // whose median is equal to s[k-1]
    public static int numberOfSubstrings(String s, int k)
    {
        int n = s.length();
 
        // Initializing vectors for storing
        // element is smaller or greater
        // than median
        int smaller[] = new int[n];
        int greater[] = new int[n];
        for (int i = 0; i < n; i++) {
            smaller[i]
                = (s.charAt(i) < s.charAt(k - 1)) ? 1 : 0;
 
            greater[i]
                = (s.charAt(i) > s.charAt(k - 1)) ? 1 : 0;
        }
 
        // Declaring a vector to store
        // difference of greater and smaller
        // characters for each position
        int diff[] = new int[n];
        for (int i = 0; i < n; i++)
            diff[i] = smaller[i] - greater[i];
 
        // Substrings in (0 to n)
        int val1 = sum(0, n, diff);
 
        // Substrings  in (0 to k-1)
        int val2 = sum(0, k - 1, diff);
 
        // Substrings in (k to n)
        int val3 = sum(k, n, diff);
 
        // Considering only those sub strings
        // with difference 0 that
        // contains s[k-1]
        return val1 - val2 - val3;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String S = "ecadgg";
        int K = 4;
 
        // Function call
        System.out.print(numberOfSubstrings(S, K));
    }
}
 
// This code is contributed by Rohit Pradhan


Python3




# Python code for the above approach
 
# Function for finding the number of
# sub strings in (start, end) where
# sum of difference is zero
def sum(start, end, v):
   
    # STL map to store number of subarrays
    # starting from index zero having
    # particular value of sum.
    prevSum = {};
 
    res = 0
    currSum = 0;
 
    for i in range(start, end):
 
        # Add current element to sum so far.
        currSum += v[i];
 
        # If currsum is equal to 0, then
        # a new subarray is found.
        # So increase count of subarrays.
        if (currSum == 0):
            res += 1
 
        if (currSum in prevSum):
            res += (prevSum[currSum]);
 
 
        # Add currsum value to count of
        # different values of sum.
        if (currSum in prevSum):
            prevSum[currSum] += 1
        else:
            prevSum[currSum] = 1
    return res;
 
# Function to find odd length substrings
# whose median is equal to s[k-1]
def numberOfSubstrings(s, k):
    n = len(s)
 
    # Initializing vectors for storing
    # element is smaller or greater
    # than median
    smaller = [0] * n
    greater = [0] * n
    for i in range(n):
        smaller[i] = s[i] < s[k - 1];
 
        greater[i] = s[i] > s[k - 1];
     
 
    # Declaring a vector to store
    # difference of greater and smaller
    # characters for each position
    diff = [0] * n
    for i in range(n):
        diff[i] = smaller[i] - greater[i];
 
    # Substrings in (0 to n)
    val1 = sum(0, n, diff);
 
    # Substrings  in (0 to k-1)
    val2 = sum(0, k - 1, diff);
 
    # Substrings in (k to n)
    val3 = sum(k, n, diff);
 
    # Considering only those sub strings
    # with difference 0 that
    # contains s[k-1]
    return val1 - val2 - val3;
 
# Driver code
S = "ecadgg";
K = 4;
 
# Function call
print(numberOfSubstrings(S, K));
 
 # This code is contributed by Saurabh Jaiswal
 
    


C#




// C# code for the above approach
 
using System;
using System.Collections;
using System.Collections.Generic;
 
public class GFG {
 
    // Function for finding the number of
    // sub strings in (start, end) where
    // sum of difference is zero
    public static int sum(int start, int end, int[] v)
    {
        // Dictionary to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        Dictionary<int, int> prevSum
            = new Dictionary<int, int>();
 
        int res = 0, currSum = 0;
 
        for (int i = start; i < end; i++) {
 
            // Add current element to sum so far.
            currSum += v[i];
 
            // If currsum is equal to 0, then
            // a new subarray is found.
            // So increase count of subarrays.
            if (currSum == 0)
                res++;
 
            if (prevSum.ContainsKey(currSum)) {
                res += prevSum[currSum];
                prevSum[currSum] += 1;
            }
            // Add currsum value to count of
            // different values of sum.
            else {
                prevSum.Add(currSum, 1);
            }
        }
 
        return res;
    }
 
    // Function to find odd length substrings
    // whose median is equal to s[k-1]
    public static int numberOfSubstrings(String s, int k)
    {
        int n = s.Length;
 
        // Initializing vectors for storing
        // element is smaller or greater
        // than median
        int[] smaller = new int[n];
        int[] greater = new int[n];
        for (int i = 0; i < n; i++) {
            smaller[i] = (s[i] < s[k - 1]) ? 1 : 0;
            greater[i] = (s[i] > s[k - 1]) ? 1 : 0;
        }
 
        // Declaring a vector to store
        // difference of greater and smaller
        // characters for each position
        int[] diff = new int[n];
        for (int i = 0; i < n; i++)
            diff[i] = smaller[i] - greater[i];
 
        // Substrings in (0 to n)
        int val1 = sum(0, n, diff);
 
        // Substrings  in (0 to k-1)
        int val2 = sum(0, k - 1, diff);
 
        // Substrings in (k to n)
        int val3 = sum(k, n, diff);
 
        // Considering only those sub strings
        // with difference 0 that
        // contains s[k-1]
        return val1 - val2 - val3;
    }
 
    static public void Main()
    {
 
        // Code
        String S = "ecadgg";
        int K = 4;
 
        // Function call
        Console.Write(numberOfSubstrings(S, K));
    }
}
 
// This code is contributed by lokeshmvs21.


Javascript




   <script>
       // JavaScript code for the above approach
 
       // Function for finding the number of
       // sub strings in (start, end) where
       // sum of difference is zero
 
       function sum(start, end, v) {
           // STL map to store number of subarrays
           // starting from index zero having
           // particular value of sum.
           let prevSum = new Map();
 
           let res = 0, currSum = 0;
 
           for (let i = start; i < end; i++) {
 
               // Add current element to sum so far.
               currSum += v[i];
 
               // If currsum is equal to 0, then
               // a new subarray is found.
               // So increase count of subarrays.
               if (currSum == 0)
                   res++;
 
               if (prevSum.has(currSum))
                   res += (prevSum.get(currSum));
 
 
               // Add currsum value to count of
               // different values of sum.
 
               if (prevSum.has(currSum))
                   prevSum.set(currSum, prevSum.get(currSum) + 1);
               else
                   prevSum.set(currSum, 1);
           }
 
           return res;
       }
 
       // Function to find odd length substrings
       // whose median is equal to s[k-1]
       function numberOfSubstrings(s, k) {
           let n = s.length;
 
           // Initializing vectors for storing
           // element is smaller or greater
           // than median
           let smaller = new Array(n).fill(0), greater = new Array(n).fill(0);
           for (let i = 0; i < n; i++) {
               smaller[i] = s[i] < s[k - 1];
 
               greater[i] = s[i] > s[k - 1];
           }
 
           // Declaring a vector to store
           // difference of greater and smaller
           // characters for each position
           let diff = new Array(n).fill(0);
           for (let i = 0; i < n; i++)
               diff[i] = smaller[i] - greater[i];
 
           // Substrings in (0 to n)
           let val1 = sum(0, n, diff);
 
           // Substrings  in (0 to k-1)
           let val2 = sum(0, k - 1, diff);
 
           // Substrings in (k to n)
           let val3 = sum(k, n, diff);
 
           // Considering only those sub strings
           // with difference 0 that
           // contains s[k-1]
           return val1 - val2 - val3;
       }
 
       // Driver code
       let S = "ecadgg";
       let K = 4;
 
       // Function call
       document.write(numberOfSubstrings(S, K));
 
// This code is contributed by Potta Lokesh
 
   </script>


Output

4

Time Complexity: O(N)
Auxiliary Space: O(N)



Similar Reads

Count substrings of same length differing by a single character from two given strings
Given two strings S and T of length N and M respectively, the task is to count the number of ways of obtaining same-length substring from both the strings such that they have a single different character. Examples: Input: S = "ab", T = "bb"Output: 3Explanation: The following are the pairs of substrings from S and T differ by a single character: ("a
7 min read
Count of substrings having the most frequent character in the string as first character
Given a string S consisting of lowercase alphabets of size N, the task is to count all substrings which contain the most frequent character in the string as the first character. Note: If more than one character has a maximum frequency, consider the lexicographically smallest among them. Examples: Input: S = "abcab"Output: 7Explanation:There are two
7 min read
Count substrings having frequency of a character exceeding that of another character in a string
Given a string S of size N consisting of characters a, b, and c only, the task is to find the number of substrings of the given string S such that the frequency of character a is greater than the frequency of character c. Examples: Input: S = "abcc"Output: 2Explanation:Below are all the possible substrings of S(= "abcc") having the frequency of the
15 min read
Print Kth character in sorted concatenated substrings of a string
Given a string of lower alphabetic characters, find K-th character in a string formed by substrings (of given string) when concatenated in sorted form. Examples: Input : str = “banana” K = 10Output : nAll substring in sorted form are,"a", "an", "ana", "anan", "anana", "b", "ba", "ban", "bana", "banan", "banana", "n", "na", "nan", "nana"Concatenated
19 min read
Lexicographically smallest permutation of a string that can be reduced to length K by removing K-length prefixes from palindromic substrings of length 2K
Given a binary string str of length N, and an integer K, the task is to find the lexicographically smallest permutation of the string str that can be reduced to length K by removal of every K-length prefix from palindromic substrings of length 2K. If no such permutation exists, print "Not Possible". Examples: Input: str = "0000100001100001”, K = 4O
14 min read
Count binary strings of length same as given string after removal of substrings "01" and "00" that consists of at least one '1'
Given a binary string S, the task is to count total binary strings consisting of at least one '1' of length equal to the length of the given string after repeatedly removing all occurrences of substrings "10" and "00" from the given string. Examples: Input: S = "111"Output: 7Explanation: Since there are no occurrences of "10" or "01" in the given s
4 min read
Kth character after replacing each character of String by its frequency exactly X times
Given a string S consisting of N digits from [1, 9] and a positive integer K and X. Every day each character of the string is replaced by its frequency and value. The task is to find the Kth character of the string after X days. Examples: Input: S = "1214", K = 10, X = 3Output: 4Explanation:1st day = "12214444"2nd day = “1222214444444444444444”3rd
8 min read
Count substrings that starts with character X and ends with character Y
Given a string str of n lowercase characters, the task is to count the number of substrings of str starting with character X and ending with character Y. Examples: Input: str = "abbcaceghcak" x = 'a', y = 'c' Output: 5 abbc, abbcac, ac, abbcaceghc, aceghc Input: str = "geeksforgeeks" x = 'g', y = 'e' Output: 6 Approach: Initialize two counters i.e.
6 min read
Count of substrings with the frequency of at most one character as Odd
Given a string S of N characters, the task is to calculate the total number of non-empty substrings such that at most one character occurs an odd number of times. Example: Input: S = "aba"Output: 4Explanation: The valid substrings are "a", "b", "a", and "aba". Therefore, the total number of required substrings are 4. Input: "aabb"Output: 9Explanati
7 min read
Check if frequency of character in one string is a factor or multiple of frequency of same character in other string
Given two strings, the task is to check whether the frequencies of a character(for each character) in one string are multiple or a factor in another string. If it is, then output "YES", otherwise output "NO". Examples: Input: s1 = "aabccd", s2 = "bbbaaaacc" Output: YES Frequency of 'a' in s1 and s2 are 2 and 4 respectively, and 2 is a factor of 4 F
6 min read
Practice Tags :