Find number of contiguous Substrings with repeated patterns
Given a string str consisting of digits, the task is to find the number of contiguous substrings such that the substring can be rearranged into a repetition of some string twice.
Examples:
Input: str=”15512212″
Output: 6
Explanation: Possible 6 substrings are :
- “1551” can be rearranged to “1515“
- “155122” can be rearranged to “152152“
- “551221” can be rearranged to “512512“
- “1221” can be rearranged to “1212“
- “55” can be rearranged to “55“
- “22” can be rearranged to “22“
Input: str=”590025995299005″
Output: 14
Approach: This can be solved with the following idea:
The approach used in the code is based on the observation that if a substring can be rearranged into a repetition of some string twice, then toggling any subset of its digits an even number of times will also result in a substring. This observation is used to efficiently compute the count of substrings using bitwise operations and maps.
Steps to implement the above approach:
- Initialize a map m with key-value pair (0, 1).
- Read the input string str.
- Initialize a variable bb to 0.
- Initialize a variable ret to 0.
- For each character c in str, do the following:
- Convert the character c to integer v by subtracting the ASCII value of ‘0‘ from it.
- Update bb by toggling the v-th bit in bb using the bitwise XOR operation.
- If m[bb] exists, increment ret by m[bb].
- Increment m[bb] by 1.
- Print the value of ret, which is the count of required contiguous substrings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void solve(string str)
{
map< int , int > m;
int bb = 0;
m[0]++;
int ret = 0;
for ( int i = 0; i < str.size(); i++) {
int v = str[i] - '0' ;
bb ^= (1 << v);
if (m.count(bb))
ret += m[bb];
m[bb]++;
}
cout << ret << endl;
}
int main()
{
string str = "15512212" ;
solve(str);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void solve(String str)
{
Map<Integer, Integer> m
= new HashMap<Integer, Integer>();
int bb = 0 ;
m.put( 0 , 1 );
int ret = 0 ;
for ( int i = 0 ; i < str.length(); i++) {
int v = str.charAt(i) - '0' ;
bb ^= ( 1 << v);
if (m.containsKey(bb))
ret += m.get(bb);
m.put(bb, m.getOrDefault(bb, 0 ) + 1 );
}
System.out.println(ret);
}
public static void main(String[] args)
{
String str = "15512212" ;
solve(str);
}
}
|
Python3
def solve(s: str ) - > None :
m = {}
bb = 0
m[ 0 ] = 1
ret = 0
for i in range ( len (s)):
v = int (s[i])
bb ^ = ( 1 << v)
if bb in m:
ret + = m[bb]
if bb not in m:
m[bb] = 0
m[bb] + = 1
print (ret)
if __name__ = = '__main__' :
s = "15512212"
solve(s)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void Solve( string str)
{
Dictionary< int , int > m = new Dictionary< int , int >();
int bb = 0;
m[0] = 1;
int ret = 0;
for ( int i = 0; i < str.Length; i++)
{
int v = str[i] - '0' ;
bb ^= (1 << v);
if (m.ContainsKey(bb))
ret += m[bb];
if (m.ContainsKey(bb))
m[bb]++;
else
m.Add(bb, 1);
}
Console.WriteLine(ret);
}
static void Main( string [] args)
{
string str = "15512212" ;
Solve(str);
}
}
|
Javascript
function solve(str) {
const m = new Map();
let bb = 0;
m.set(0, 1);
let ret = 0;
for (let i = 0; i < str.length; i++) {
const v = parseInt(str[i]);
bb ^= (1 << v);
if (m.has(bb)) {
ret += m.get(bb);
}
m.set(bb, (m.get(bb) || 0) + 1);
}
console.log(ret);
}
const str = "15512212" ;
solve(str);
|
Time Complexity: O(n*log(m))
Auxilairy Space: O(m)
Related articles:
Last Updated :
22 Aug, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...