Open In App

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

Last Updated : 16 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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;
}


Java




import java.util.*;
 
public class Main {
  public static boolean isSorted(String s) {
    for (int i = 0; i < s.length() - 1; i++) {
      if (s.charAt(i) > s.charAt(i + 1)) {
        return false;
      }
    }
    return true;
  }
 
  public static String chooseStr(String s, String b) {
    Map<Character, Integer> m = new HashMap<>();
    Set<String> ss = new TreeSet<>(Collections.reverseOrder());
 
    // Count frequencies of characters
    for (int i = 0; i < b.length(); i++) {
      m.put(b.charAt(i), m.getOrDefault(b.charAt(i), 0) + 1);
    }
    int g = b.length() / 2;
    int c = 0;
    String k = "", p;
    String[] split = s.split(" ");
 
    // Traverse through sentence
    for (int i = 0; i < split.length; i++) {
      c = 0;
      p = split[i];
      for (int j = 0; j < p.length(); j++) {
        if (m.containsKey(p.charAt(j))) {
          c++;
        }
        if (c == g) {
          break;
        }
      }
 
      // Store the output according
      // to the given conditions
      if ((c == 1 && isSorted(p)) || c == g) {
        ss.add(p);
      }
    }
 
    // Lexicographically largest string
    for (String i : ss) {
      k += i + " ";
    }
    return k;
  }
 
  public static void main(String[] args) {
    String s = "peek fit and run";
    String b = "ekta";
    System.out.println(chooseStr(s, b));
  }
}
 
// This code is contributed by anskalyan3.


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>


C#




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace GFG
{
    class Program
    {
        static void Main(string[] args)
        {
            string S = "peek fit and run";
            string B = "ekta";
            int N = S.Length;
 
            Console.WriteLine(ChooseStr(S, B, N));
            Console.ReadLine();
        }
 
        private static string ChooseStr(string s, string b, int n)
        {
            Dictionary<char, int> m = new Dictionary<char, int>();
            SortedSet<string> ss = new SortedSet<string>(Comparer<string>.Create((x, y) => y.CompareTo(x)));
 
            foreach (char c in b)
            {
                if (m.ContainsKey(c))
                {
                    m++;
                }
                else
                {
                    m = 1;
                }
            }
 
            int g = b.Length / 2;
            int cnt = 0;
            string k = "";
            string[] words = s.Split(' ');
 
            foreach (string p in words)
            {
                cnt = 0;
                foreach (char c in p)
                {
                    if (m.ContainsKey(c))
                    {
                        cnt++;
                    }
                    if (cnt == g)
                    {
                        break;
                    }
                }
 
                if ((cnt == 1 && Isosorted(p)) || cnt == g)
                {
                    ss.Add(p);
                }
            }
 
            foreach (string i in ss)
            {
                k += i;
            }
 
            return k;
        }
 
        private static bool Isosorted(string s)
        {
            for (int i = 0; i < s.Length - 1; i++)
            {
                if (s[i] > s[i + 1])
                {
                    return false;
                }
            }
            return true;
        }
    }
}


 
 

Output

peekfit

 

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

 



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

Similar Reads