Open In App

Divide given numeric string into at most two increasing subsequences which form an increasing string upon concatenation

Last Updated : 10 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:
    1. 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.
    2. Initialize a boolean variable flag as 1 that stores whether the processed subsequence is valid or not.
    3. 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.
    4. Check if the value of last is greater than pos, then modify the value of flag as 0.
    5. 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)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads