Minimize count of alternating subsequences to divide given Binary String with subsequence number
Last Updated :
23 Nov, 2021
Given a binary string S of length N. The task is to find the following:
- The minimum number of subsequences, string S can be divided into, such that the subsequence does not contain adjacent zeroes or ones.
- Subsequence number to which each character of string S belongs.
If there are many answers, output any.
Examples:
Input: S = “0011”, N = 4
Output:
2
1 2 2 1
Explanation:
There can be a minimum of 2 subsequences such that they donot have any adjacent zeroes or ones.
Subsequence 1: “01”
Subsequence 2: “01”
Also, the first character of S(‘0’) belongs to subsequence 1(“01”)
Second character of S(‘0’) belongs to subsequence 2(“01”)
Third character of S(‘1’) belongs to subsequence 2(“01”)
Fourth character of S(‘1’) belongs to subsequence 1(“01”)
Input: S = “1000110”, N = 7
Output:
3
1 1 2 3 3 2 2
Approach: It is to be noted that a subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements. Now, follow the steps below to solve the problem:
- Create a vector ans to store the subsequences to which each character of string S belongs.
- Also, create two vectors endZero and endOne to store the subsequences ending with ‘0’ and ‘1’ respectively.
- As there can’t be adjacent zeroes or ones in a subsequence. Hence, if a character is ‘0’, the next character to be put in the subsequence must be ‘1’ and vice versa.
- Now, using a loop traverse over each character of S and check if it is ‘0’ or ‘1’. Also, declare a variable newSeq which represents the new subsequence to be formed if consecutive zeroes or ones are encountered.
- If a character is ‘0’, check whether the vector endOne is empty or not:
- If it is empty, then push newSeq into endZero.
- Otherwise, put the last subsequence of endOne into newSeq. Now, this last subsequence of endOne does not end with ‘1’ anymore as ‘0’ has been appended to it. Thus, push it in endZero.
- Similarly, if a character in S is ‘1’, the same steps as above are followed, i.e., check whether vector endZero is empty or not:
- If it is empty, then push newSeq into endOne.
- Otherwise, put the last subsequence of endZero into newSeq. Now, this last subsequence of endZero does not end with ‘0’ anymore as ‘1’ has been appended to it. Thus, push it in endOne.
- Then, push newSeq into vector ans.
- Repeat the above steps for each character of S.
- The minimum number of subsequences will be given by the sum of the sizes of endZero and endOne.
- Finally, output the minimum number of subsequences and the vector ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findSeq(string S, int N)
{
vector< int > ans(N);
vector< int > endZero, endOne;
for ( int i = 0; i < N; ++i) {
int newSeq = endZero.size()
+ endOne.size();
if (S[i] == '0' ) {
if (endOne.empty()) {
endZero.push_back(newSeq);
}
else {
newSeq = endOne.back();
endOne.pop_back();
endZero.push_back(newSeq);
}
}
else {
if (endZero.empty()) {
endOne.push_back(newSeq);
}
else {
newSeq = endZero.back();
endZero.pop_back();
endOne.push_back(newSeq);
}
}
ans[i] = newSeq;
}
cout << endZero.size()
+ endOne.size()
<< endl;
for ( int i = 0; i < N; ++i) {
cout << ans[i] + 1 << " " ;
}
}
int main()
{
string S = "1000110" ;
int N = 7;
findSeq(S, N);
return 0;
}
|
Java
import java.util.ArrayList;
class GFG {
public static void findSeq(String S, int N)
{
int [] ans = new int [N];
ArrayList<Integer> endZero = new ArrayList<Integer>();
ArrayList<Integer> endOne = new ArrayList<Integer>();
for ( int i = 0 ; i < N; ++i) {
int newSeq = endZero.size() + endOne.size();
if (S.charAt(i) == '0' ) {
if (endOne.isEmpty()) {
endZero.add(newSeq);
} else {
newSeq = endOne.get(endOne.size() - 1 );
endOne.remove(endOne.size() - 1 );
endZero.add(newSeq);
}
} else {
if (endZero.isEmpty()) {
endOne.add(newSeq);
} else {
newSeq = endZero.get(endZero.size() - 1 );
endZero.remove(endZero.size() - 1 );
endOne.add(newSeq);
}
}
ans[i] = newSeq;
}
System.out.println(endZero.size() + endOne.size());
for ( int i = 0 ; i < N; ++i) {
System.out.print(ans[i] + 1 + " " );
}
}
public static void main(String args[]) {
String S = "1000110" ;
int N = 7 ;
findSeq(S, N);
}
}
|
Python3
def findSeq(S, N):
ans = [ 0 for _ in range (N)]
endZero = []
endOne = []
for i in range ( 0 , N):
newSeq = len (endZero) + len (endOne)
if (S[i] = = '0' ):
if ( len (endOne) = = 0 ):
endZero.append(newSeq)
else :
newSeq = endOne[ len (endOne) - 1 ]
endOne.pop()
endZero.append(newSeq)
else :
if ( len (endZero) = = 0 ):
endOne.append(newSeq)
else :
newSeq = endZero[ len (endZero) - 1 ]
endZero.pop()
endOne.append(newSeq)
ans[i] = newSeq
print ( len (endZero) + len (endOne))
for i in range ( 0 , N):
print (ans[i] + 1 , end = " " )
if __name__ = = "__main__" :
S = "1000110"
N = 7
findSeq(S, N)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public static void findSeq(String S, int N)
{
int [] ans = new int [N];
List< int > endZero = new List< int >();
List< int > endOne = new List< int >();
for ( int i = 0; i < N; ++i)
{
int newSeq = endZero.Count + endOne.Count;
if (S[i] == '0' )
{
if (endOne.Count == 0)
{
endZero.Add(newSeq);
}
else
{
newSeq = endOne[endOne.Count - 1];
endOne.Remove(endOne.Count - 1);
endZero.Add(newSeq);
}
}
else
{
if (endZero.Count == 0)
{
endOne.Add(newSeq);
}
else
{
newSeq = endZero[endZero.Count - 1];
endZero.Remove(endZero.Count - 1);
endOne.Add(newSeq);
}
}
ans[i] = newSeq;
}
Console.WriteLine(endZero.Count + endOne.Count);
for ( int i = 0; i < N; ++i)
{
Console.Write(ans[i] + 1 + " " );
}
}
public static void Main()
{
String S = "1000110" ;
int N = 7;
findSeq(S, N);
}
}
|
Javascript
<script>
function findSeq(S, N)
{
let ans = new Array(N);
let endZero = [], endOne = [];
for (let i = 0; i < N; ++i) {
let newSeq = endZero.length
+ endOne.length;
if (S[i] == '0' ) {
if (endOne.length == 0) {
endZero.push(newSeq);
}
else {
newSeq = endOne[endOne.length - 1];
endOne.pop();
endZero.push(newSeq);
}
}
else {
if (endZero.length == 0) {
endOne.push(newSeq);
}
else {
newSeq = endZero[endZero.length - 1];
endZero.pop();
endOne.push(newSeq);
}
}
ans[i] = newSeq;
}
document.write(endZero.length
+ endOne.length
+ '<br>' );
for (let i = 0; i < N; ++i) {
document.write(ans[i] + 1 + " " );
}
}
let S = "1000110" ;
let N = 7;
findSeq(S, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...