Check if any permutation of a given string is lexicographically larger than the other given string


We have given two strings and need to check whether the given string's permutations exist such that one permutation can have a larger character than another permutation at the ith index.

We can solve the problem by sorting the string and comparing each character of the string one by one. Also, we can solve the problem using the frequency of characters of both strings.

Problem statement – We have given a string str1 and str2 of length N. We need to check whether any permutations of both strings exist such that the permutation of one string is lexicographically larger than the other. It means any permutation should have a larger character at the ith index than other string’s permutation’s ith index character.

Sample examples

Input – str1 = "aef"; str2 = "fgh";

Output– Yes

Explanation– The ‘fgh’ is already greater than ‘aef’. Here, a > f, g > e, h > f.

Input – str1 = "adsm"; str2 = "obpc";

Output– No

Explanation– We can’t find any permutation of both strings such that every character of one is greater than the other permutation.

Approach 1

In this approach, we will sort both strings in lexicographical order. After that, we will compare each character of the string. If all characters of str1 are smaller than str2, or all character of str2 is smaller than str1, return true. Else we return false.

Algorithm

  • Use the sort() method to sort the string.

  • Define the isStr1Greater boolean variable and initialize with true.

  • Traverse the string, and if any character at the ith index in str1 is smaller than str2, update the value of isStr1Greater to false and use the break keyword to break the loop

  • If isStr1Greater is true, the loop is completed successfully and returned true.

  • Now, traverse the string to check whether the str2 is greater than str1. If we find any character of str1 is greater, return false.

  • Return true if the loop is completed successfully.

Example

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

bool isAnyPermLarge(string string1, string string2) {
   // sort the strings
   sort(string1.begin(), string1.end());
   sort(string2.begin(), string2.end());
   // to keep track if string1 is greater than string2
   bool isStr1Greater = true;
   // traverse the string
   for (int i = 0; i < string1.length(); i++) {
      // if any character of string1 is less than string2, return false.
      if (string1[i] < string2[i]) {
          isStr1Greater = false;
          break;
      }
   }
   // If string1 is greater, returning true
   if (isStr1Greater)
      return true;
   // traverse the string
   for (int i = 0; i < string2.length(); i++) {
      // if any character of string2 is less than string1, return false.
      if (string1[i] > string2[i]) {
          return false;
      }
   }
   // return true if string2 is greater than string1
   return true;
}
int main() {
   string string1 = "aef";
   string string2 = "fgh";
   bool res = isAnyPermLarge(string1, string2);
   if (res) {
      cout << "Yes, permutation exists such that one string is greater than the other.";
   } else {
      cout << "No, permutation does not exist such that one string is greater than the other.";
   }
   return 0;
}

Output

Yes, permutation exists such that one string is greater than the other.

Time complexity – O(N*logN) as we sort the strings.

Space complexity – O(N) is required to sort the strings.

Approach 2

In this approach, we will store the total frequency of each character in both strings. After that, we will decide whether we can find any string permutations such that one is larger than the other using the cumulative frequency.

Algorithm

  • Define the map1 and map2 array of length 26 and initialize with zero.

  • Store the frequency of characters of str1 to map1 and str2 to map2.

  • Define the isStr1 and isStr2 boolean variables and initialize with false to track whether the str1 is larger or str2.

  • Define the cnt1 and cnt2 variables to store the cumulative frequency of string characters.

  • Traverse map1 and map2. Add map1[i] to cnt1 and map2[i] to cnt2.

  • If cnt1 is greater than cnt2, cumulative frequency up to character at the ith index is greater for str1. If so, and str2 is already greater, return false. Else, change isStr1 to true

  • If cnt2 is greater than cnt1, cumulative frequency up to character at the ith index is greater for str2. If so, and str1 is already greater, return false. Else, change isStr2 to true

  • Return true at the end.

Example

#include <iostream>
#include <string>
using namespace std;

bool isAnyPermLarge(string string1, string string2) {
   int map1[26] = {0};
   int map2[26] = {0};
   // store the frequency of each character in the map1
   for (int i = 0; i < string1.length(); i++) {
      map1[string1[i] - 'a']++;
   }
   // store the frequency of each character in the map2
   for (int i = 0; i < string2.length(); i++) {
      map2[string2[i] - 'a']++;
   }
   // To keep track of which string is smaller. Initially, both strings are equal.
   bool isStr1 = false, isStr2 = false;
   // to count the cumulative frequency of characters of both strings
   int cnt1 = 0, cnt2 = 0;
   // traverse for all characters.
   for (int i = 0; i < 26; i++) {
      // update the cumulative frequency of characters
      cnt1 += map1[i];
      cnt2 += map2[i];
      if (cnt1 > cnt2) {
          // If string2 is already greater and cumulative frequency of string1 is greater than string2, then return false
          if (isStr2)
              return false;
          // update isStr1 to true as string1 is smaller
          isStr1 = true;
      }
      if (cnt1 < cnt2) {
          // If string1 is already greater and cumulative frequency of string2 is greater than string1, then return false
          if (isStr1)
              return false;
          // update isStr2 to true as string2 is smaller
          isStr2 = true;
      }
   }
   return true;
}
int main() {
   string string1 = "aef";
   string string2 = "fgh";
   bool res = isAnyPermLarge(string1, string2);
   if (res) {
      cout << "Yes, permutation exists such that one string is greater than the other.";
   } else {
      cout << "No, permutation does not exist such that one string is greater than the other.";
   }
   return 0;
}

Output

Yes, permutation exists such that one string is greater than the other.

Time complexity – O(N) as we count the frequency of characters.

Space complexity – O(26) as we store the frequency of characters in an array.

We learned to check whether any permutation of both strings exists such that all characters of one can be greater than another. The first approach uses the sorting method, and the second approach uses the cumulative frequency of characters.

Updated on: 17-Aug-2023

50 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements