# Lexicographically smallest and largest anagrams of a string containing another string as its substring

Given two strings S1 of size N and S2 of size M, the task is to find the lexicographically smallest and the largest anagrams of S1 such that it contains the string S2 as a substring.

Examples:

Input: S1 = “hheftaabzzdr”, S2 = “earth”
Output: abdearthfhzz, zzhfearthdba
Explanation:
The smallest anagram of the given string S1 with S2 as a substring is “abdearthfhzz”
The largest anagram of the given string S1 with s2 as a substring is “zzhfearthdba”

Input: S1 = “ethgakagmenpgs”, S2 = “geeks”
Output: aageeksgghmnpt, tpmnhgggeeksaa
Explanation:
The smallest anagram of the given string S1 with S2 as a substring is “aageeksgghmnpt”
The largest anagram of the given string S1 with S2 as a substring is “tpmnhgggeeksaa”

Naive Approach: The simplest approach is to find all possible anagrams of S1 and check if any of those anagrams contain S2 as a substring or not. If yes, then find the lexicographically smallest and the largest among them.

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

Efficient Approach: The idea is to first generate the lexicographically smallest anagram character by character and then find the lexicographically largest anagram by reversing the smallest anagram except for the substring which contains S2. Below are the steps:

1. Initialize a map M and store the frequency of each character present in S1
2. Maintain a Set S which stores the distinct characters present in S1.
3. Decrease the frequency of characters of S1 from M which are already present in S2.
4. Initialize an empty string res which will store the lexicographically largest anagram.
5. Iterate over the set S, if the first character of string S2 is encountered while traversing the set values, check if the second distinct character of S2 is greater than the current character of Set. If so, then add all the characters of S2 to res.
6. Otherwise, keep on iterating the Set and add the characters to res.

Below is the implementation of the above approach:

## C++14

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Function to find the lexicographically` `// smallest anagram of string` `// which contains another string` `pair lexico_smallest(string s1, ` `                                  ``string s2)` `{`   `    ``// Initializing the map and set` `    ``map<``char``, ``int``> M;` `    ``set<``char``> S;` `    ``pair pr;`   `    ``// Iterating over s1` `    ``for` `(``int` `i = 0; i <= s1.size() - 1; ++i) {`   `        ``// Storing the frequency of` `        ``// characters present in s1` `        ``M[s1[i]]++;`   `        ``// Storing the distinct` `        ``// characters present in s1` `        ``S.insert(s1[i]);` `    ``}`   `    ``// Decreasing the frequency of ` `    ``// characters from M that` `    ``// are already present in s2` `    ``for` `(``int` `i = 0; i <= s2.size() - 1; ++i) {` `        ``M[s2[i]]--;` `    ``}`   `    ``char` `c = s2;` `    ``int` `index = 0;` `    ``string res = ``""``;`   `    ``// Traversing alphabets` `    ``// in sorted order` `    ``for` `(``auto` `x : S) {`   `        ``// If current character of set` `        ``// is not equal to current ` `        ``// character of s2` `        ``if` `(x != c) {` `            ``for` `(``int` `i = 1; i <= M[x]; ++i) {` `                ``res += x;` `            ``}` `        ``}` `        ``else` `{`   `            ``// If element is equal to ` `            ``// current character of s2` `            ``int` `j = 0;` `            ``index = res.size();`   `            ``// Checking for second` `            ``// distinct character in s2` `            ``while` `(s2[j] == x) {` `                ``j++;` `            ``}`   `            ``// s2[j] will store` `            ``// second distinct charcter` `            ``if` `(s2[j] < c) {` `                ``res += s2;` `                ``for` `(``int` `i = 1; i <= M[x]; ++i) {` `                    ``res += x;` `                ``}` `            ``}` `            ``else` `{` `                ``for` `(``int` `i = 1; i <= M[x]; ++i) {` `                    ``res += x;` `                ``}` `                ``index += M[x];` `                ``res += s2;` `            ``}` `        ``}` `    ``}`   `    ``pr.first = res;` `    ``pr.second = index;`   `    ``// Return the answer` `    ``return` `pr;` `}`   `// Function to find the lexicographically` `// largest anagram of string` `// which contains another string` `string lexico_largest(string s1, string s2)` `{`   `    ``// Getting the lexicographically` `    ``// smallest anagram` `    ``pair pr = lexico_smallest(s1, s2);`   `    ``// d1 stores the prefix` `    ``string d1 = ``""``;` `    ``for` `(``int` `i = pr.second - 1; i >= 0; i--) {` `        ``d1 += pr.first[i];` `    ``}`   `    ``// d2 stores the suffix` `    ``string d2 = ``""``;` `    ``for` `(``int` `i = pr.first.size() - 1;` `         ``i >= pr.second + s2.size(); --i) {` `        ``d2 += pr.first[i];` `    ``}`   `    ``string res = d2 + s2 + d1;`   `    ``// Return the result` `    ``return` `res;` `}`   `// Driver Code` `int` `main()` `{` `    ``// Given two strings` `    ``string s1 = ``"ethgakagmenpgs"``;` `    ``string s2 = ``"geeks"``;`   `    ``// Function Calls` `    ``cout << lexico_smallest(s1, s2).first` `         ``<< ``"\n"` `;` `    ``cout << lexico_largest(s1, s2);`   `    ``return` `(0);` `}`

## Java

 `// Java program for the above approach ` `import` `java.lang.*;` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG{ ` `    `  `// Function to find the lexicographically ` `// smallest anagram of string ` `// which contains another string ` `static` `String[] lexico_smallest(String s1,  ` `                                ``String s2) ` `{ ` `    `  `    ``// Initializing the map and set ` `    ``Map M = ``new` `HashMap<>();` `    ``Set S = ``new` `TreeSet<>(); ` `   `  `    ``// Iterating over s1 ` `    ``for``(``int` `i = ``0``; i <= s1.length() - ``1``; ++i)` `    ``{ ` `        `  `        ``// Storing the frequency of ` `        ``// characters present in s1 ` `        ``if` `(!M.containsKey(s1.charAt(i)))` `            ``M.put(s1.charAt(i), ``1``);` `        ``else` `            ``M.replace(s1.charAt(i), ` `                ``M.get(s1.charAt(i)) + ``1``);` `  `  `        ``// Storing the distinct ` `        ``// characters present in s1 ` `        ``S.add(s1.charAt(i));` `    ``} ` `  `  `    ``// Decreasing the frequency of  ` `    ``// characters from M that ` `    ``// are already present in s2 ` `    ``for``(``int` `i = ``0``; i <= s2.length() - ``1``; ++i) ` `    ``{ ` `        ``if` `(M.containsKey(s2.charAt(i)))` `            ``M.replace(s2.charAt(i), ` `                ``M.get(s2.charAt(i)) - ``1``);` `    ``} ` `  `  `    ``char` `c = s2.charAt(``0``);` `    ``int` `index = ``0``; ` `    ``String res = ``""``; ` `  `  `    ``// Traversing alphabets ` `    ``// in sorted order ` `    ``Iterator it = S.iterator();` `    ``while` `(it.hasNext())` `    ``{` `        ``char` `x = it.next();` `        `  `        ``// If current character of set ` `        ``// is not equal to current  ` `        ``// character of s2 ` `        ``if` `(x != c) ` `        ``{ ` `            ``for``(``int` `i = ``1``; i <= M.get(x); ++i) ` `            ``{ ` `                ``res += x; ` `            ``} ` `        ``} ` `        ``else` `        ``{ ` `            `  `            ``// If element is equal to  ` `            ``// current character of s2 ` `            ``int` `j = ``0``; ` `            ``index = res.length(); ` `            `  `            ``// Checking for second ` `            ``// distinct character in s2 ` `            ``while` `(s2.charAt(j) == x) ` `            ``{ ` `                ``j++; ` `            ``} ` `            `  `            ``// s2[j] will store ` `            ``// second distinct charcter ` `            ``if` `(s2.charAt(j) < c)` `            ``{ ` `                ``res += s2; ` `                ``for``(``int` `i = ``1``; i <= M.get(x); ++i) ` `                ``{ ` `                    ``res += x; ` `                ``} ` `            ``} ` `            ``else` `            ``{ ` `                ``for``(``int` `i = ``1``; i <= M.get(x); ++i) ` `                ``{ ` `                    ``res += x; ` `                ``} ` `                ``index += M.get(x); ` `                ``res += s2; ` `            ``} ` `        ``} ` `    ``} ` `    ``String pr[] = {res, index + ``""``};` `    ``return` `pr;` `} `   `// Function to find the lexicographically ` `// largest anagram of string ` `// which contains another string ` `static` `String lexico_largest(String s1, String s2) ` `{ ` `    `  `    ``// Getting the lexicographically ` `    ``// smallest anagram ` `    ``String pr[] = lexico_smallest(s1, s2); ` `  `  `    ``// d1 stores the prefix ` `    ``String d1 = ``""``; ` `    ``for``(``int` `i = Integer.valueOf(pr[``1``]) - ``1``; ` `            ``i >= ``0``; i--) ` `    ``{ ` `        ``d1 += pr[``0``].charAt(i);` `    ``} ` `  `  `    ``// d2 stores the suffix ` `    ``String d2 = ``""``; ` `    ``for``(``int` `i = pr[``0``].length() - ``1``; ` `            ``i >= Integer.valueOf(pr[``1``]) + ` `                                 ``s2.length();` `            ``--i)` `    ``{ ` `        ``d2 += pr[``0``].charAt(i);` `    ``} ` `    `  `    ``String res = d2 + s2 + d1; ` `    `  `    ``// Return the result ` `    ``return` `res; ` `} `   `// Driver Code` `public` `static` `void` `main (String[] args) ` `{` `    `  `    ``// Given two strings ` `    ``String s1 = ``"ethgakagmenpgs"``; ` `    ``String s2 = ``"geeks"``; ` `    `  `    ``// Function Calls ` `    ``System.out.println(lexico_smallest(s1, s2)[``0``]);` `    ``System.out.println(lexico_largest(s1, s2));` `}` `}`   `// This code is contributed by jyoti369`

Output:

```aageeksgghmnpt
tpnmhgggeeksaa

```

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : jyoti369