Lexicographically largest string formed by choosing words from given Sentence as per given Pattern
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 ; } } } |
peekfit
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...