Skip to content
Related Articles

Related Articles

Lexicographically largest string formed by choosing words from given Sentence as per given Pattern

View Discussion
Improve Article
Save Article
Like Article
  • Difficulty Level : Hard
  • Last Updated : 22 Jun, 2022

Given a sentence S and a string B having distinct characters, find a string by joining the words of S according to given conditions:-

  • Choose a word from S if
    • It has at least length(B)/2 characters from string B or
    • Having at least one character from string B and lexicographically sorted in increasing order.
  • The string formed should be lexicographically largest string.

Examples:

Input: S = “peek geek suv”, B = “ekps”
Output: suvpeekgeek
Explanation: “suv” has one character from B and sorted in increasing order.
Whereas “peek” and “geek” has length(B)/2 characters.

Input: S = “peek fit and run”, B = “ekta”
Output: peekfit  

 

Naive Approach: The task can be solved by storing both the word of string S and the string B in a set and comparing if they are equal but this would require more than one set, which requires extra time and space.

Time Complexity: O(N * logN) where N is the total number of characters in S
Auxiliary Space: O(N)

Efficient approach: The better approach is to use a map. Following the steps mentioned below:

  • Store the frequency of characters of B in an unordered map and compare with strings of array S.
  • If two characters exist in a word of string S  then add it to the output string.
  • If only one character is present then check if it is sorted in lexicographically increasing order.
  • If yes then add it to the output string.
  • Arrange the output string in lexicographically largest permutation.

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Check if sorted or not
bool isosrted(string s)
{
    for (int i = 0; i < s.size() - 1; i++) {
        if (s[i] > s[i + 1])
            return false;
    }
    return true;
}
 
// Function to get the lexicographically largest string
string choosestr(string s, string b, int n)
{
    unordered_map<char, int> m;
    set<string, greater<string> > ss;
 
    // Count frequencies of characters
    for (int i = 0; b[i]; i++) {
        m[b[i]]++;
    }
    int g = b.size() / 2;
    int c = 0;
    string k = "", p;
    stringstream sg(s);
 
    // Traverse through sentence
    while (sg >> p) {
        c = 0;
        for (int j = 0; j < p.size(); j++) {
            if (m[p[j]])
                c++;
            if (c == g)
                break;
        }
 
        // Store the output according
        // to the given conditions
        if ((c == 1 and isosrted(p)) or c == g)
            ss.insert(p);
    }
 
    // Lexicographically largest string
    for (auto i : ss) {
        k += i;
    }
    return k;
}
 
// Driver code
int main()
{
    string S = "peek fit and run";
    string B = "ekta";
    int N = sizeof(S) / sizeof(S[0]);
    cout << choosestr(S, B, N);
    return 0;
}

Python3




# Python program for the above approach:
 
## Check if sorted or not
def isosrted(s):
    for i in range(len(s)-1):
        if (s[i] > s[i + 1]):
            return False
    return True
 
## Function to get the lexicographically largest string
def choosestr(s, b, n):
    m = {};
    ss =set({})
 
    ## Count frequencies of characters
    for i in range(len(b)):
        if (b[i] in m):
            m[b[i]]+=1
        else:
            m[b[i]] = 1
     
    g = len(b) // 2
    c = 0
    k = "";
    arr = s.split(" ");
 
    ## Traverse through sentence
    for p in arr:
        c = 0
        for j in range(len(p)):
            if (p[j] in m):
                c+=1
            if (c == g):
                break
 
        ## Store the output according
        ## to the given conditions
        if ((c == 1 and isosrted(p)) or c == g):
            ss.add(p)
 
    ans = []
    for i in ss:
        ans.append(i)
    ans.sort()
    ans.reverse()
 
    ## Lexicographically largest string
    for i in ans:
        k += i
    return k
 
## Driver code
if __name__ == '__main__':
    S = "peek fit and run"
    B = "ekta"
    N = len(S)
    print(choosestr(S, B, N))
     
    # This code is contributed by subhamgoyal2014.

Javascript




<script>
    // JavaScript code for the above approach
 
    // Check if sorted or not
    const isosrted = (s) => {
        for (let i = 0; i < s.length - 1; i++) {
            if (s[i] > s[i + 1])
                return false;
        }
        return true;
    }
 
    // Function to get the lexicographically largest string
    const choosestr = (s, b, n) => {
        let m = {};
        let ss = new Set();
 
        // Count frequencies of characters
        for (let i = 0; i < b.length; i++) {
            if (b[i] in m) m[b[i]]++;
            else m[b[i]] = 1;
        }
        let g = parseInt(b.length / 2);
        let c = 0;
        let k = "";
        let p = s.split(" ");
 
        // Traverse through sentence
        for (let i in p) {
            c = 0;
            for (let j = 0; j < p[i].length; j++) {
                if (p[i][j] in m)
                    c++;
                if (c == g)
                    break;
            }
 
            // Store the output according
            // to the given conditions
            if ((c == 1 && isosrted(p[i])) || c == g) {
                ss.add(p[i]);
            }
        }
 
        // Lexicographically largest string
        for (let i of ss) {
            k += i;
        }
        return k;
    }
 
    // Driver code
 
    let S = "peek fit and run";
    let B = "ekta";
    let N = S.length;
    document.write(choosestr(S, B, N));
 
    // This code is contributed by rakeshsahni
 
</script>

 
 

Output

peekfit

 

Time Complexity: O(N)
Auxiliary Space: O(N)

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!