Core Java

Check if Two Strings Are Permutations of Each Other in Java

In this article, we will explore different approaches to check if two strings are permutations of each other in Java.

1. What Is a String Permutation?

A string permutation is a rearrangement of the characters of the string into a different sequence. Two strings are considered permutations of each other if they contain the same characters with the same frequencies, but possibly in a different order. For example, the strings “abc” and “bca” are permutations of each other.

2. Sorting

One way to check if two strings are permutations of each other is to sort both strings and compare them. If the sorted versions of both strings are equal, then the strings are permutations of each other.

import java.util.Arrays;

public class PermutationCheck {
    public static boolean arePermutations(String str1, String str2) {
        if (str1.length() != str2.length()) {
            return false;
        }

        char[] charArray1 = str1.toCharArray();
        char[] charArray2 = str2.toCharArray();

        Arrays.sort(charArray1);
        Arrays.sort(charArray2);

        return Arrays.equals(charArray1, charArray2);
    }

    public static void main(String[] args) {
        String str1 = "listen";
        String str2 = "silent";

        boolean result = arePermutations(str1, str2);
        System.out.println("Are the two strings permutations of each other? " + result);
    }
}

In the above code:

  • We first check if the lengths of the two strings are equal. If not, they cannot be permutations.
  • We convert both strings to character arrays and sort these arrays.
  • We compare the sorted character arrays using Arrays.equals. If they are equal, the strings are permutations of each other.

The code returns the following output:

Are the two strings permutations of each other? True

3. Count Frequencies

Another method to check for permutations is to count the frequency of each character in both strings and compare these counts.

import java.util.HashMap;

public class PermutationCheck {
    public static boolean arePermutations(String str1, String str2) {
        if (str1.length() != str2.length()) {
            return false;
        }

        HashMap<Character, Integer> charCountMap = new HashMap<>();

        for (char c : str1.toCharArray()) {
            charCountMap.put(c, charCountMap.getOrDefault(c, 0) + 1);
        }

        for (char c : str2.toCharArray()) {
            if (!charCountMap.containsKey(c)) {
                return false;
            }

            charCountMap.put(c, charCountMap.get(c) - 1);
            if (charCountMap.get(c) == 0) {
                charCountMap.remove(c);
            }
        }

        return charCountMap.isEmpty();
    }

    public static void main(String[] args) {
        String str1 = "apple";
        String str2 = "papel";

        boolean result = arePermutations(str1, str2);
        System.out.println("Are the two strings permutations of each other? " + result);
    }
}

In the above code:

  • We check if the lengths of the two strings are equal.
  • We create a HashMap to count the frequency of each character in the first string.
  • We iterate over the second string, decrementing the count of each character in the HashMap.
  • If a character is not found in the HashMap or its count goes to zero, we remove it from the map.
  • If the HashMap is empty at the end, the strings are permutations of each other.

The code returns the following output:

Are the two strings permutations of each other? True

4. String That Contains a Permutation

To check if one string contains a permutation of another string, we can use a sliding window approach along with character frequency counting.

import java.util.HashMap;

public class PermutationCheck {
    public static boolean containsPermutation(String s1, String s2) {
        if (s1.length() > s2.length()) {
            return false;
        }

        HashMap<Character, Integer> s1Count = new HashMap<>();
        HashMap<Character, Integer> s2Count = new HashMap<>();

        for (int i = 0; i < s1.length(); i++) {
            s1Count.put(s1.charAt(i), s1Count.getOrDefault(s1.charAt(i), 0) + 1);
            s2Count.put(s2.charAt(i), s2Count.getOrDefault(s2.charAt(i), 0) + 1);
        }

        int matches = 0;
        for (char c : s1Count.keySet()) {
            if (s1Count.get(c).equals(s2Count.get(c))) {
                matches++;
            }
        }

        for (int i = 0; i < s2.length() - s1.length(); i++) {
            if (matches == s1Count.size()) {
                return true;
            }

            char start = s2.charAt(i);
            char end = s2.charAt(i + s1.length());

            if (s2Count.get(start).equals(s1Count.get(start))) {
                matches--;
            }
            s2Count.put(start, s2Count.get(start) - 1);
            if (s2Count.get(start).equals(s1Count.get(start))) {
                matches++;
            }

            if (s2Count.containsKey(end)) {
                if (s2Count.get(end).equals(s1Count.get(end))) {
                    matches--;
                }
                s2Count.put(end, s2Count.get(end) + 1);
                if (s2Count.get(end).equals(s1Count.get(end))) {
                    matches++;
                }
            } else {
                s2Count.put(end, 1);
            }
        }

        return matches == s1Count.size();
    }

    public static void main(String[] args) {
        String s1 = "ab";
        String s2 = "eidbaooo";

        boolean result = containsPermutation(s1, s2);
        System.out.println("Does the second string contain a permutation of the first? " + result);
    }
}

In the above code:

  • We first check if the length of the first string is greater than the second string. If so, it cannot contain a permutation.
  • We use two HashMaps to count the frequencies of characters in the first string and in the current window of the second string.
  • We slide the window over the second string, updating the counts and the number of matches between the two HashMaps.
  • If the number of matches equals the size of the first string’s character count map, the second string contains a permutation of the first.

The code returns the following output:

Does the second string contain a permutation of the first? True

5. Summary

MethodAdvantagesDisadvantages
Sorting
  • Simple implementation.
  • Efficient for small to moderate-sized strings.
  • Time complexity is O(n log n) due to sorting.
  • Requires additional space proportional to the length of strings.
Count Frequencies
  • Efficient for large strings as it operates in linear time O(n).
  • Requires less additional space compared to the sorting method.
  • May require more complex logic to implement correctly.
  • Uses extra space proportional to the character set (constant space for ASCII, larger for Unicode).
String Contains a Permutation
  • Can efficiently determine if one string contains a permutation of another using a sliding window approach.
  • Operates in linear time O(n), suitable for large strings.
  • Requires careful handling of edge cases and window sliding.
  • May be slightly more complex to implement compared to simpler methods.

6. Conclusion

When determining if two strings are permutations of each other in Java, different methods offer various trade-offs in terms of efficiency, simplicity, and space complexity. Choosing the appropriate method depends on the specific requirements of the application:

  • Sorting is suitable for scenarios where simplicity of implementation is prioritized and where string lengths are not excessively large.
  • Count Frequencies is ideal for applications where efficiency for large strings is crucial and where additional space usage can be managed.
  • String Contains a Permutation is beneficial for scenarios where checking substrings efficiently within large strings is required, despite the added complexity of implementation.

Overall, understanding these methods and their trade-offs allows developers to choose the most appropriate approach based on the specific constraints and requirements of their Java applications.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button