Counting Good Substrings with 0s, 1s, and ?s
Last Updated :
09 Jan, 2024
Given a string S consisting of characters 0,1,? A string is called good if all the adjacent characters in it are different i.e. of the form 0101010… or 1010101… You can replace ? with 0 or 1. Your task is to determine the number of good contiguous substrings of the string S.
Constraint: |S|<200000;
Example:
Input: S=0?10
Output: 8
Input: S = ???
Output: 6
Approach:
The idea is to uses dynamic programming to efficiently count the number of good contiguous substrings in a given string. It maintains a 2D array lst to store the last occurrences of ‘0’ and ‘1’ at even and odd positions separately. The main loop iterates through each character in the string, updating the index j based on the last occurrences and calculating the number of good substrings by adding the difference between the current index and j to the answer. Our would algorithm considers the patterns ’01’ and ’10’, treating ‘?’ as a wildcard. The last occurrences of ‘0’ and ‘1’ are updated for each character, and the final answer is returned.
Step-by-step approach:
- Initialize a 2D vector to store the last occurrence indices of ‘0’ and ‘1’
- Initialize a variable ans to store the answer
- Iterate through each character in the string
- Determine the parity of the current index (0 or 1)
- Update j based on the last occurrences of ‘0’ and ‘1’ in the previous parity positions
- Update the answer by adding the difference between the current index and j (i.e, ans += i – j).
- Update the last occurrence indices for the current character
- Return the answer (ans).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve(string& s)
{
vector<vector< int > > dp(2, vector< int >(2, -1));
long long ans = 0;
for ( int i = 0; i < int (s.size()); ++i) {
int j = i - 1;
int p = i & 1;
if (s[i] != '1' )
j = min(j, max(dp[0][p ^ 1], dp[1][p]));
if (s[i] != '0' )
j = min(j, max(dp[0][p], dp[1][p ^ 1]));
ans += i - j;
if (s[i] != '?' )
dp[s[i] - '0' ][p] = i;
}
return ans;
}
int main()
{
string s = "0?10";
int result = solve(s);
cout << result;
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
public static long solve(String s) {
int [][] dp = new int [ 2 ][ 2 ];
for ( int [] row : dp) {
Arrays.fill(row, - 1 );
}
long ans = 0 ;
for ( int i = 0 ; i < s.length(); ++i) {
int j = i - 1 ;
int p = i & 1 ;
if (s.charAt(i) != '1' ) {
j = Math.min(j, Math.max(dp[ 0 ][p ^ 1 ], dp[ 1 ][p]));
}
if (s.charAt(i) != '0' ) {
j = Math.min(j, Math.max(dp[ 0 ][p], dp[ 1 ][p ^ 1 ]));
}
ans += i - j;
if (s.charAt(i) != '?' ) {
dp[s.charAt(i) - '0' ][p] = i;
}
}
return ans;
}
public static void main(String[] args) {
String s = "0?10" ;
long result = solve(s);
System.out.println(result);
}
}
|
Python3
def GFG(s):
dp = [[ - 1 , - 1 ] for _ in range ( 2 )]
ans = 0
for i in range ( len (s)):
j = i - 1
p = i % 2
if s[i] ! = '1' :
j = min (j, max (dp[ 0 ][p ^ 1 ], dp[ 1 ][p]))
if s[i] ! = '0' :
j = min (j, max (dp[ 0 ][p], dp[ 1 ][p ^ 1 ]))
ans + = i - j
if s[i] ! = '?' :
dp[ int (s[i])][p] = i
return ans
s = "0?10"
result = GFG(s)
print (result)
|
C#
using System;
class Program
{
static long Solve( string s)
{
int [,] dp = new int [2, 2] { { -1, -1 }, { -1, -1 } };
long ans = 0;
for ( int i = 0; i < s.Length; ++i)
{
int j = i - 1;
int p = i % 2;
if (s[i] != '1' )
j = Math.Min(j, Math.Max(dp[0, p ^ 1], dp[1, p]));
if (s[i] != '0' )
j = Math.Min(j, Math.Max(dp[0, p], dp[1, p ^ 1]));
ans += i - j;
if (s[i] != '?' )
dp[s[i] - '0' , p] = i;
}
return ans;
}
static void Main()
{
string s = "0?10" ;
long result = Solve(s);
Console.WriteLine(result);
}
}
|
Javascript
function GFG(s) {
let dp = Array.from({ length: 2 }, () => Array(2).fill(-1));
let ans = 0;
for (let i = 0; i < s.length; ++i) {
let j = i - 1;
let p = i % 2;
if (s[i] !== '1' ) {
j = Math.min(j, Math.max(dp[0][p ^ 1], dp[1][p]));
}
if (s[i] !== '0' ) {
j = Math.min(j, Math.max(dp[0][p], dp[1][p ^ 1]));
}
ans += i - j;
if (s[i] !== '?' ) {
dp[parseInt(s[i])][p] = i;
}
}
return ans;
}
let s = "0?10" ;
let result = GFG(s);
console.log(result);
|
Time complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...