Divide given numeric string into at most two increasing subsequences which form an increasing string upon concatenation
Last Updated :
10 Mar, 2023
Given a string S consisting of N digits, the task is to partition the string into at most two increasing subsequences such that concatenation of them also forms an increasing string. If it is not possible to do so, then print "-1".
Examples:
Input: S = “040425524644”
Output: 0022444 44556
Explanation:
One of the possible way to partition the given string S is {"0022444", "44556"}. Both are in increasing order and the concatenation of them are also increasing "0022444" + '"4556" = "002244444556".
Therefore, print both the subsequence formed.
Input: S = "123456789"
Output: 123456789
Naive Approach: The simplest approach to solve the problem is to generate all possible subsequences and check whether any two non-overlapping subsequences satisfy the given condition or not. If found to be true, then print both the two subsequences.
Time Complexity: O(N*2N)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by putting all the values less than X in the first subsequence and all the elements greater than X in the second subsequence and all the elements equal to X is decided on the basis of their position for all X in the range [0, 9]. Follow the steps below to solve the problem:
- Initialize a variable say, pos to store the position where less than pos are in the first subsequence, greater than pos in the second subsequence, and element equal to pos will be on the subsequence based on their position.
- Initialize an array res[] that will store which element belongs to which subsequence.
- Iterate pos in the range [0, 9] and perform the following steps:
- Initialize two variables last1 as 0 and last2 as pos which stores the last elements that have been put in subsequence 1 and 2 respectively.
- Initialize a boolean variable flag as 1 that stores whether the processed subsequence is valid or not.
- Iterate in the range [0, N-1] using i as a variable and perform the following steps:
- If last2 ≤ S[i], then modify the value of last2 as S[i] and res[i] as 2.
- Otherwise if last1 ≤ S[i], then modify the value of last1 as S[i] and res[i] as 1.
- Otherwise, modify the value of the flag as 0.
- Check if the value of last is greater than pos, then modify the value of flag as 0.
- If the value of flag is 1, then print the array res as the answer and break out of the loop.
- After completing the above steps, print -1 if no possible subsequence has been found.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to check for valid subsequences
void findSubsequence(string str)
{
int n = str.size();
// Stores which element belongs to
// which subsequence
char res[n];
for (int i = 0; i < n; i++)
res[i] = 0;
// Check for each pos if a possible
// subsequence exist or not
for (int pos = 0; pos <= 9; pos++) {
// Last member of 1 subsequence
char lst1 = '0';
bool flag = 1;
// Last Member of 2nd subsequence
char lst2 = pos + '0';
for (int i = 0; i < n; i++) {
// Check if current element can
// go to 2nd subsequence
if (lst2 <= str[i]) {
res[i] = '2';
lst2 = str[i];
}
// Check if the current elements
// belongs to first subsequence
else if (lst1 <= str[i]) {
res[i] = '1';
lst1 = str[i];
}
// If the current element does
// not belong to any subsequence
else
flag = 0;
}
// Check if last digit of first
// subsequence is greater than pos
if (lst1 > pos + '0')
flag = 0;
// If a subsequence is found,
// find the subsequences
if (flag) {
// Stores the resulting
// subsequences
string S1 = "";
string S2 = "";
for (int i = 0; i < n; i++) {
if (res[i] == '1') {
S1 += str[i];
}
else {
S2 += str[i];
}
}
// Print the subsequence
cout << S1 << ' ' << S2 << endl;
return;
}
}
// If no subsequence found, print -1
cout << "-1";
}
// Driver Code
int main()
{
string S = "040425524644";
findSubsequence(S);
S = "123456789";
findSubsequence(S);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
public class GFG{
// Function to check for valid subsequences
static void findSubsequence(String str)
{
int n = str.length();
// Stores which element belongs to
// which subsequence
char []res = new char[n];
for (int i = 0; i < n; i++)
res[i] = 0;
// Check for each pos if a possible
// subsequence exist or not
for (int pos = 0; pos <= 9; pos++) {
// Last member of 1 subsequence
char lst1 = '0';
boolean flag = true;
// Last Member of 2nd subsequence
char lst2 = (char) (pos + '0');
for (int i = 0; i < n; i++) {
// Check if current element can
// go to 2nd subsequence
if (lst2 <= str.charAt(i)) {
res[i] = '2';
lst2 = str.charAt(i);
}
// Check if the current elements
// belongs to first subsequence
else if (lst1 <= str.charAt(i)) {
res[i] = '1';
lst1 = str.charAt(i);
}
// If the current element does
// not belong to any subsequence
else
flag = false;
}
// Check if last digit of first
// subsequence is greater than pos
if (lst1 > pos + '0')
flag = false;
// If a subsequence is found,
// find the subsequences
if (flag) {
// Stores the resulting
// subsequences
String S1 = "";
String S2 = "";
for (int i = 0; i < n; i++) {
if (res[i] == '1') {
S1 += str.charAt(i);
}
else {
S2 += str.charAt(i);
}
}
// Print the subsequence
System.out.print(S1 + " " + S2 +"\n");
return;
}
}
// If no subsequence found, print -1
System.out.print("-1");
}
// Driver Code
public static void main(String[] args)
{
String S = "040425524644";
findSubsequence(S);
S = "123456789";
findSubsequence(S);
}
}
// This code is contributed by 29AjayKumar.
Python3
# Python 3 program for the above approach
# Function to check for valid subsequences
def findSubsequence(str):
n = len(str)
# Stores which element belongs to
# which subsequence
res = ['0' for i in range(n)]
# Check for each pos if a possible
# subsequence exist or not
for pos in range(10):
# Last member of 1 subsequence
lst1 = '0'
flag = 1
# Last Member of 2nd subsequence
lst2 = chr(pos + 48)
for i in range(n):
# Check if current element can
# go to 2nd subsequence
if (lst2 <= str[i]):
res[i] = '2'
lst2 = str[i]
# Check if the current elements
# belongs to first subsequence
elif(lst1 <= str[i]):
res[i] = '1'
lst1 = str[i]
# If the current element does
# not belong to any subsequence
else:
flag = 0
# Check if last digit of first
# subsequence is greater than pos
if (lst1 > chr(pos + 48)):
flag = 0
# If a subsequence is found,
# find the subsequences
if (flag):
# Stores the resulting
# subsequences
S1 = ""
S2 = ""
for i in range(n):
if (res[i] == '1'):
S1 += str[i]
else:
S2 += str[i]
# Print the subsequence
print(S1,S2)
return
# If no subsequence found, print -1
print("-1")
# Driver Code
if __name__ == '__main__':
S = "040425524644"
findSubsequence(S)
S = "123456789"
findSubsequence(S)
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for the approach
using System;
using System.Collections.Generic;
class GFG {
// Function to check for valid subsequences
static void findSubsequence(string str)
{
int n = str.Length;
// Stores which element belongs to
// which subsequence
char[] res = new char[n];
for (int i = 0; i < n; i++)
res[i] = '0';
// Check for each pos if a possible
// subsequence exist or not
for (int pos = 0; pos <= 9; pos++) {
// Last member of 1 subsequence
char lst1 = '0';
bool flag = true;
// Last Member of 2nd subsequence
char lst2 = (char) (pos + '0');
for (int i = 0; i < n; i++) {
// Check if current element can
// go to 2nd subsequence
if (lst2 <= str[i]) {
res[i] = '2';
lst2 = str[i];
}
// Check if the current elements
// belongs to first subsequence
else if (lst1 <= str[i]) {
res[i] = '1';
lst1 = str[i];
}
// If the current element does
// not belong to any subsequence
else
flag = false;
}
// Check if last digit of first
// subsequence is greater than pos
if (lst1 > pos + '0')
flag = false;
// If a subsequence is found,
// find the subsequences
if (flag) {
// Stores the resulting
// subsequences
string S1 = "";
string S2 = "";
for (int i = 0; i < n; i++) {
if (res[i] == '1') {
S1 += str[i];
}
else {
S2 += str[i];
}
}
// Print the subsequence
Console.WriteLine(S1 + ' ' + S2);
return;
}
}
// If no subsequence found, print -1
Console.Write("-1");
}
// Driver Code
public static void Main()
{
string S = "040425524644";
findSubsequence(S);
S = "123456789";
findSubsequence(S);
}
}
// This code is contributed by sanjoy_62.
JavaScript
<script>
// JavaScript Program to implement
// the above approach
// Function to check for valid subsequences
function findSubsequence(str) {
let n = str.length;
// Stores which element belongs to
// which subsequence
let res = new Array(n);
for (let i = 0; i < n; i++)
res[i] = 0;
// Check for each pos if a possible
// subsequence exist or not
for (let pos = 0; pos <= 9; pos++) {
// Last member of 1 subsequence
let lst1 = '0';
let flag = 1;
// Last Member of 2nd subsequence
let lst2 = String.fromCharCode(pos + '0'.charCodeAt(0));
for (let i = 0; i < n; i++) {
// Check if current element can
// go to 2nd subsequence
if (lst2.charCodeAt(0) <= str[i].charCodeAt(0)) {
res[i] = '2';
lst2 = str[i];
}
// Check if the current elements
// belongs to first subsequence
else if (lst1.charCodeAt(0) <= str[i].charCodeAt(0)) {
res[i] = '1';
lst1 = str[i];
}
// If the current element does
// not belong to any subsequence
else
flag = 0;
}
// Check if last digit of first
// subsequence is greater than pos
if (lst1.charCodeAt(0) > pos + '0'.charCodeAt(0)) {
flag = 0;
}
// If a subsequence is found,
// find the subsequences
if (flag) {
// Stores the resulting
// subsequences
let S1 = "";
let S2 = "";
for (let i = 0; i < n; i++) {
if (res[i] == '1') {
S1 += str[i];
}
else {
S2 += str[i];
}
}
// Print the subsequence
document.write(S1 + ' ' + S2 + '<br>');
return;
}
}
// If no subsequence found, print -1
document.write("-1");
}
// Driver Code
let S = "040425524644";
findSubsequence(S);
S = "123456789";
findSubsequence(S);
// This code is contributed by Potta Lokesh
</script>
Output: 0022444 44556
123456789
Time Complexity: O(N^2)
Auxiliary Space: O(N)
Similar Reads
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
Concatenate the strings in an order which maximises the occurrence of subsequence "ab" Given N strings containing of characters 'a' and 'b'. These string can be concatenated in any order to make a single final string S. The score of the final string S is defined as the number of occurrences of the subsequence "ab" in it. Now, the task is to concatenate the string in such a way that th
12 min read
Minimize count of alternating subsequences to divide given Binary String with subsequence number 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, outp
11 min read
Count ways to partition a number into increasing sequences of digits Given a numeric string S, the task is to find the number of ways to partition a string into substrings consisting of digits in increasing order. Examples: Input: S = "1345"Output: 5Explanation: Possible partitions are as follows: [1345][13, 45], [1, 345][1, 3, 45][1, 3, 4, 5] Input: S = "12"Output:
8 min read
Divide array into increasing and decreasing subsequence without changing the order Given a merged sequence which consists of two sequences which got merged, one of them was strictly increasing and the other was strictly decreasing. Elements of increasing sequence were inserted between elements of the decreasing one without changing the order. Sequences [1, 3, 4] and [10, 4, 2] can
11 min read