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: 8Input: 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:
#include <bits/stdc++.h> using namespace std;
int solve(string& s)
{ // Initialize a 2D vector to store the last occurrence
// indices of '0' and '1'
vector<vector< int > > dp(2, vector< int >(2, -1));
// Initialize a variable to store the answer
long long ans = 0;
// Iterate through each character in the string
for ( int i = 0; i < int (s.size()); ++i) {
int j = i - 1; // Initialize j to the previous index
// Determine the parity of the current index (0 or
// 1)
int p = i & 1;
// Update j based on the last occurrences of '0' and
// '1' in the previous parity positions
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]));
// Update the answer by adding the difference
// between the current index and j
ans += i - j;
// Update the last occurrence indices for the
// current character
if (s[i] != '?' )
dp[s[i] - '0' ][p] = i;
}
// Output the answer for the current test case
return ans;
} int main()
{ // Input string
string s = "0?10";
int result = solve(s);
cout << result;
return 0;
} |
import java.util.Arrays;
public class Main {
public static long solve(String s) {
// Initialize a 2D array to store the last occurrence
// indices of '0' and '1'
int [][] dp = new int [ 2 ][ 2 ];
for ( int [] row : dp) {
Arrays.fill(row, - 1 );
}
// Initialize a variable to store the answer
long ans = 0 ;
// Iterate through each character in the string
for ( int i = 0 ; i < s.length(); ++i) {
int j = i - 1 ; // Initialize j to the previous index
// Determine the parity of the current index (0 or 1)
int p = i & 1 ;
// Update j based on the last occurrences of '0' and
// '1' in the previous parity positions
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 ]));
}
// Update the answer by adding the difference
// between the current index and j
ans += i - j;
// Update the last occurrence indices for the
// current character
if (s.charAt(i) != '?' ) {
dp[s.charAt(i) - '0' ][p] = i;
}
}
// Output the answer for the current test case
return ans;
}
public static void main(String[] args) {
// Input string
String s = "0?10" ;
long result = solve(s);
System.out.println(result);
}
} // This code is contributed by shivamgupta0987654321 |
def GFG(s):
# Initialize a 2D array to store the last occurrence
dp = [[ - 1 , - 1 ] for _ in range ( 2 )]
# Initialize a variable to store the answer
ans = 0
# Iterate through each character in the string
for i in range ( len (s)):
j = i - 1
# Determine the parity of the current index (0 or 1)
p = i % 2
# Check if the current character is not '1'
if s[i] ! = '1' :
j = min (j, max (dp[ 0 ][p ^ 1 ], dp[ 1 ][p]))
# Check if the current character is not '0'
if s[i] ! = '0' :
j = min (j, max (dp[ 0 ][p], dp[ 1 ][p ^ 1 ]))
# Update the answer by adding the difference
# between the current index and j
ans + = i - j
# Update the last occurrence indices for the current character
if s[i] ! = '?' :
dp[ int (s[i])][p] = i
# Output the answer for the current test case
return ans
# Input string s = "0?10"
result = GFG(s)
print (result)
|
using System;
class Program
{ static long Solve( string s)
{
// Initialize a 2D array to store the last occurrence
// indices of '0' and '1'
int [,] dp = new int [2, 2] { { -1, -1 }, { -1, -1 } };
// Initialize a variable to store the answer
long ans = 0;
// Iterate through each character in the string
for ( int i = 0; i < s.Length; ++i)
{
int j = i - 1; // Initialize j to the previous index
// Determine the parity of the current index (0 or 1)
int p = i % 2;
// Update j based on the last occurrences of '0' and
// '1' in the previous parity positions
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]));
// Update the answer by adding the difference
// between the current index and j
ans += i - j;
// Update the last occurrence indices for the
// current character
if (s[i] != '?' )
dp[s[i] - '0' , p] = i;
}
// Output the answer for the current test case
return ans;
}
static void Main()
{
// Input string
string s = "0?10" ;
long result = Solve(s);
Console.WriteLine(result);
}
} |
function GFG(s) {
// Initialize a 2D array to the store the last occurrence
let dp = Array.from({ length: 2 }, () => Array(2).fill(-1));
// Initialize a variable to store the answer
let ans = 0;
// Iterate through each character in the string
for (let i = 0; i < s.length; ++i) {
let j = i - 1;
// Determine the parity of the current index (0 or 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]));
}
// Update the answer by adding the difference
// between current index and j
ans += i - j;
// Update the last occurrence indices for the current character
if (s[i] !== '?' ) {
dp[parseInt(s[i])][p] = i;
}
}
// Output the answer for the current test case
return ans;
} // Input string let s = "0?10" ;
let result = GFG(s); console.log(result); |
8
Time complexity: O(N)
Auxiliary Space: O(1)