Check valid Substring of at least k length
Last Updated :
05 Dec, 2023
Given a string s (‘a’ <= s[i] <= ‘z’) and an integer k (1 <= k < n <= 105), the task is to check if any valid substrings of at least k length exist in the given string. A substring is valid if the occurrences of each character in the substring should be even.
Examples:
Input: s = “bba”, k = 2
Output: true
Explanation: Below is valid substring: “bba” -> “bb”
Input: s = “aba”, k = 2
Output: false
Check valid substring of at least k length using Bit masking:
Use Bitmasking to encode visited characters from index 0 to i and increment the count if the same mask occurred before.
Step-by-step approach:
- Create a map dp to store the first occurance of any mask of substring.
- Initialize dp[0] = -1, for one possible valid substring (if we don’t consider any character from the string).
- Iterate through the string from i = 0 to N-1.
- Calculate the current mask for the current character at the (S[i] – ‘a’) index.
- Check if same current mask exist in dp.
- If true then find the current substring length by (i – dp[current mask), if it is greater than or equal to k, return true
-
- Update the current mask with current index i in dp.
- Finally, return false.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long long allvalidString(string& word, int k)
{
unordered_map< long long , long long > dp;
long long mask = 0, result = 0;
dp[0] = -1;
for ( int i = 0; i < word.size(); i++) {
char ch = word[i];
mask ^= 1 << (ch - 'a' );
if (dp.find(mask) != dp.end()) {
if (i - dp[mask] >= k)
return true ;
}
else {
dp[mask] = i;
}
}
return false ;
}
int main()
{
string s = "bba";
int k = 2;
cout << (allvalidString(s, k) ? " true " : " false ");
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static boolean allValidString(String word, int k) {
Map<Long, Long> dp = new HashMap<>();
long mask = 0 ;
long result = 0 ;
dp.put(0L, -1L);
for ( int i = 0 ; i < word.length(); i++) {
char ch = word.charAt(i);
mask ^= 1L << (ch - 'a' );
if (dp.containsKey(mask)) {
if (i - dp.get(mask) >= k) {
return true ;
}
} else {
dp.put(mask, ( long )i);
}
}
return false ;
}
public static void main(String[] args) {
String s = "bba" ;
int k = 2 ;
System.out.println(allValidString(s, k) ? "true" : "false" );
}
}
|
Python
def all_valid_strings(word, k):
dp = {}
mask = 0
result = 0
dp[ 0 ] = - 1
for i in range ( len (word)):
ch = word[i]
mask ^ = 1 << ( ord (ch) - ord ( 'a' ))
if mask in dp:
if i - dp[mask] > = k:
return True
else :
dp[mask] = i
return False
s = "bba"
k = 2
print ( "true" if all_valid_strings(s, k) else "false" )
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static bool AllValidString( string word, int k)
{
Dictionary< long , long > dp
= new Dictionary< long , long >();
long mask = 0;
dp[0L] = -1L;
for ( int i = 0; i < word.Length; i++) {
char ch = word[i];
mask ^= 1L << (ch - 'a' );
if (dp.ContainsKey(mask)) {
if (i - dp[mask] >= k) {
return true ;
}
}
else {
dp[mask] = i;
}
}
return false ;
}
public static void Main( string [] args)
{
string s = "bba" ;
int k = 2;
Console.WriteLine(AllValidString(s, k) ? "true"
: "false" );
}
}
|
Javascript
function allvalidString(word, k) {
const dp = new Map();
let mask = 0;
let result = 0;
dp.set(0, -1);
for (let i = 0; i < word.length; i++) {
const ch = word[i].charCodeAt(0);
mask ^= 1 << (ch - 'a' );
if (dp.has(mask)) {
if (i - dp.get(mask) >= k) {
return true ;
}
} else {
dp.set(mask, i);
}
}
return false ;
}
const s = "bba" ;
const k = 2;
console.log(allvalidString(s, k) ? "true" : "false" );
|
Time Complexity: O(N), where n is the length of the given string
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...