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; } |
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> |
peekfit
Time Complexity: O(N)
Auxiliary Space: O(N)