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++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum number of
// subsequences into which S has to divide
// and the subsequences to which each character
// of S belongs to.
void findSeq(string S, int N)
{
// Stores the subsequences to which each
// character of S belongs to.
vector<int> ans(N);
// Store the subsequences ending with zeroes
// and ones respectively.
vector<int> endZero, endOne;
// Loop to traverse each character of S
for (int i = 0; i < N; ++i) {
// Stores the number of new
// subsequence to be formed
int newSeq = endZero.size()
+ endOne.size();
// If the character is '0'
if (S[i] == '0') {
// If there is no string
// which ends with '1'
if (endOne.empty()) {
// Push newSeq into endZero
endZero.push_back(newSeq);
}
else {
// Put the last element
// of endOne into newSeq
newSeq = endOne.back();
// Remove the last
// element of endOne
endOne.pop_back();
// newSeq ends with '0'
endZero.push_back(newSeq);
}
}
else {
// If there is no string
// which ends with '0'
if (endZero.empty()) {
// Push newSeq into endOne
endOne.push_back(newSeq);
}
else {
// Put the last element
// of endZero into newSeq
newSeq = endZero.back();
// Remove the last element of endOne
endZero.pop_back();
// newSeq ends with '1'
endOne.push_back(newSeq);
}
}
// Put newSeq into vector ans
ans[i] = newSeq;
}
// Output the minimum
// number of subsequences
cout << endZero.size()
+ endOne.size()
<< endl;
// Output the subsequences
// to which each character
// of S belongs to
for (int i = 0; i < N; ++i) {
// Add 1 as the index starts from 0
cout << ans[i] + 1 << " ";
}
}
// Driver Code
int main()
{
// Given input
string S = "1000110";
int N = 7;
// Function Call
findSeq(S, N);
return 0;
}
Java
// Java program for the above approach
import java.util.ArrayList;
class GFG {
// Function to find the minimum number of
// subsequences into which S has to divide
// and the subsequences to which each character
// of S belongs to.
public static void findSeq(String S, int N)
{
// Stores the subsequences to which each
// character of S belongs to.
int[] ans = new int[N];
// Store the subsequences ending with zeroes
// and ones respectively.
ArrayList<Integer> endZero = new ArrayList<Integer>();
ArrayList<Integer> endOne = new ArrayList<Integer>();
// Loop to traverse each character of S
for (int i = 0; i < N; ++i) {
// Stores the number of new
// subsequence to be formed
int newSeq = endZero.size() + endOne.size();
// If the character is '0'
if (S.charAt(i) == '0') {
// If there is no string
// which ends with '1'
if (endOne.isEmpty()) {
// Push newSeq into endZero
endZero.add(newSeq);
} else {
// Put the last element
// of endOne into newSeq
newSeq = endOne.get(endOne.size() - 1);
// Remove the last
// element of endOne
endOne.remove(endOne.size() - 1);
// newSeq ends with '0'
endZero.add(newSeq);
}
} else {
// If there is no string
// which ends with '0'
if (endZero.isEmpty()) {
// Push newSeq into endOne
endOne.add(newSeq);
} else {
// Put the last element
// of endZero into newSeq
newSeq = endZero.get(endZero.size() - 1);
// Remove the last element of endOne
endZero.remove(endZero.size() - 1);
// newSeq ends with '1'
endOne.add(newSeq);
}
}
// Put newSeq into vector ans
ans[i] = newSeq;
}
// Output the minimum
// number of subsequences
System.out.println(endZero.size() + endOne.size());
// Output the subsequences
// to which each character
// of S belongs to
for (int i = 0; i < N; ++i) {
// Add 1 as the index starts from 0
System.out.print(ans[i] + 1 + " ");
}
}
// Driver Code
public static void main(String args[]) {
// Given input
String S = "1000110";
int N = 7;
// Function Call
findSeq(S, N);
}
}
// This code is contributed by gfgking.
Python3
# python program for the above approach
# Function to find the minimum number of
# subsequences into which S has to divide
# and the subsequences to which each character
# of S belongs to.
def findSeq(S, N):
# Stores the subsequences to which each
# character of S belongs to.
ans = [0 for _ in range(N)]
# Store the subsequences ending with zeroes
# and ones respectively.
endZero = []
endOne = []
# Loop to traverse each character of S
for i in range(0, N):
# Stores the number of new
# subsequence to be formed
newSeq = len(endZero) + len(endOne)
# If the character is '0'
if (S[i] == '0'):
# If there is no string
# which ends with '1'
if (len(endOne) == 0):
# Push newSeq into endZero
endZero.append(newSeq)
else:
# Put the last element
# of endOne into newSeq
newSeq = endOne[len(endOne) - 1]
# Remove the last
# element of endOne
endOne.pop()
# newSeq ends with '0'
endZero.append(newSeq)
else:
# If there is no string
# which ends with '0'
if (len(endZero) == 0):
# Push newSeq into endOne
endOne.append(newSeq)
else:
# Put the last element
# of endZero into newSeq
newSeq = endZero[len(endZero) - 1]
# Remove the last element of endOne
endZero.pop()
# newSeq ends with '1'
endOne.append(newSeq)
# Put newSeq into vector ans
ans[i] = newSeq
# Output the minimum
# number of subsequences
print(len(endZero) + len(endOne))
# Output the subsequences
# to which each character
# of S belongs to
for i in range(0, N):
# Add 1 as the index starts from 0
print(ans[i] + 1, end=" ")
# Driver Code
if __name__ == "__main__":
# Given input
S = "1000110"
N = 7
# Function Call
findSeq(S, N)
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the minimum number of
// subsequences into which S has to divide
// and the subsequences to which each character
// of S belongs to.
public static void findSeq(String S, int N)
{
// Stores the subsequences to which each
// character of S belongs to.
int[] ans = new int[N];
// Store the subsequences ending with zeroes
// and ones respectively.
List<int> endZero = new List<int>();
List<int> endOne = new List<int>();
// Loop to traverse each character of S
for (int i = 0; i < N; ++i)
{
// Stores the number of new
// subsequence to be formed
int newSeq = endZero.Count + endOne.Count;
// If the character is '0'
if (S[i] == '0')
{
// If there is no string
// which ends with '1'
if (endOne.Count == 0)
{
// Push newSeq into endZero
endZero.Add(newSeq);
}
else
{
// Put the last element
// of endOne into newSeq
newSeq = endOne[endOne.Count - 1];
// Remove the last
// element of endOne
endOne.Remove(endOne.Count - 1);
// newSeq ends with '0'
endZero.Add(newSeq);
}
}
else
{
// If there is no string
// which ends with '0'
if (endZero.Count == 0)
{
// Push newSeq into endOne
endOne.Add(newSeq);
}
else
{
// Put the last element
// of endZero into newSeq
newSeq = endZero[endZero.Count - 1];
// Remove the last element of endOne
endZero.Remove(endZero.Count - 1);
// newSeq ends with '1'
endOne.Add(newSeq);
}
}
// Put newSeq into vector ans
ans[i] = newSeq;
}
// Output the minimum
// number of subsequences
Console.WriteLine(endZero.Count + endOne.Count);
// Output the subsequences
// to which each character
// of S belongs to
for (int i = 0; i < N; ++i)
{
// Add 1 as the index starts from 0
Console.Write(ans[i] + 1 + " ");
}
}
// Driver Code
public static void Main()
{
// Given input
String S = "1000110";
int N = 7;
// Function Call
findSeq(S, N);
}
}
// This code is contributed by gfgking.
JavaScript
<script>
// JavaScript Program to implement
// the above approach
// Function to find the minimum number of
// subsequences into which S has to divide
// and the subsequences to which each character
// of S belongs to.
function findSeq(S, N)
{
// Stores the subsequences to which each
// character of S belongs to.
let ans = new Array(N);
// Store the subsequences ending with zeroes
// and ones respectively.
let endZero = [], endOne = [];
// Loop to traverse each character of S
for (let i = 0; i < N; ++i) {
// Stores the number of new
// subsequence to be formed
let newSeq = endZero.length
+ endOne.length;
// If the character is '0'
if (S[i] == '0') {
// If there is no string
// which ends with '1'
if (endOne.length == 0) {
// Push newSeq into endZero
endZero.push(newSeq);
}
else {
// Put the last element
// of endOne into newSeq
newSeq = endOne[endOne.length - 1];
// Remove the last
// element of endOne
endOne.pop();
// newSeq ends with '0'
endZero.push(newSeq);
}
}
else {
// If there is no string
// which ends with '0'
if (endZero.length == 0) {
// Push newSeq into endOne
endOne.push(newSeq);
}
else {
// Put the last element
// of endZero into newSeq
newSeq = endZero[endZero.length - 1];
// Remove the last element of endOne
endZero.pop();
// newSeq ends with '1'
endOne.push(newSeq);
}
}
// Put newSeq into vector ans
ans[i] = newSeq;
}
// Output the minimum
// number of subsequences
document.write(endZero.length
+ endOne.length
+ '<br>');
// Output the subsequences
// to which each character
// of S belongs to
for (let i = 0; i < N; ++i) {
// Add 1 as the index starts from 0
document.write(ans[i] + 1 + " ");
}
}
// Driver Code
// Given input
let S = "1000110";
let N = 7;
// Function Call
findSeq(S, N);
// This code is contributed by Potta Lokesh
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Number of subsequences in a given binary string divisible by 2 Given binary string str of length N, the task is to find the count of subsequences of str which are divisible by 2. Leading zeros in a sub-sequence are allowed. Examples: Input: str = "101" Output: 2 "0" and "10" are the only subsequences which are divisible by 2.Input: str = "10010" Output: 22 Naiv
4 min read
Minimum number whose binary form is not a subsequence of given binary string Given a binary string S of size N, the task is to find the minimum non-negative integer which is not a subsequence of the given string S in its binary form. Examples: Input: S = "0000"Output:1Explanation: 1 whose binary representation is "1" is the smallest non-negative integer which is not a subseq
8 min read
Number of alternating substrings from a given Binary String Given a binary string of size N, the task is to count the number of alternating substrings that are present in the string S. Examples: Input: S = "0010"Output: 7Explanation: All the substring of the string S are: {"0", "00", "001", "0010", "0", "01", "010", "1", "10", "0"}Strings that are alternatin
13 min read
Count subsequences 01 in string generated by concatenation of given numeric string K times Given a string S and a positive integer K, the task is to find the number of subsequences "01" in the string generated by concatenation of the given numeric string S K times. Examples: Input: S = "0171", K = 2Output: 6Explanation:The string formed by concatenation of S, K number of times is "0171017
6 min read
Periodic Binary String With Minimum Period and a Given Binary String as Subsequence. Periodic Binary String: A Binary string is called periodic if it can be written as a repetition of a binary string of smaller or same length. For example, 101010 is a periodic binary string with period 10 as we can get the string by repeatedly appending 10 to itself. In general, the string S with pe
5 min read
Minimum number of flips with rotation to make binary string alternating Given a binary string S of 0s and 1s. The task is to make the given string a sequence of alternate characters by using the below operations: Remove some prefix from the start and append it to the end.Flip some or every bit in the given string. Print the minimum number of bits to be flipped to make t
11 min read
Generate Binary String with equal number of 01 and 10 Subsequence Given an integer N (N > 2), the task is to generate a binary string of size N that consists of equal numbers of "10" & "01" subsequences and also the string should contain at least one '0' and one '1' Note: If multiple such strings exist, print any. Examples: Input: 4Output: 0110Explanation :
7 min read
Number of subsequences in a string divisible by n Given a string consisting of digits 0-9, count the number of subsequences in it divisible by m.Examples: Input : str = "1234", n = 4Output : 4The subsequences 4, 12, 24 and 124 are divisible by 4. Input : str = "330", n = 6Output : 4The subsequences 30, 30, 330 and 0 are divisible by n.Input : str =
11 min read
Increase the count of given subsequences by optimizing the Array Given an array X[] of length N. Which contains the alternate frequency of 0s and 1s in Binary String starting from 0. Then the task is to maximize the count of the "01" subsequence where you can choose two different elements of X[], let's say Xi and Xj such that abs (i - j) = 2, and then swap Xi and
11 min read
Maximum count of â010..â subsequences that can be removed from given Binary String Given a binary string S consisting of size N, the task is to find the maximum number of binary subsequences of the form "010.." of length at least 2 that can be removed from the given string S. Examples: Input: S = "110011010"Output: 3Explanation:Following are the subsequence removed:Operation 1: Ch
6 min read