Leetcode: Group Anagrams






Now I'm onto an alternative LeetCode problem, named group anagrams, and the problem description is as follows:


Given an array of strings strs, group the anagrams together, and I can return the answer in any order. This problem set is used in Amazon, Goldman Sachs, and various other companies. I actually believe that I have received this problem once during a coding challenge  when applying to one of them.


Here's an actual example:


Input: strs = ["eat","tea","tan","ate","nat","bat"]

Output: [["bat"],["nat","tan"],["ate","eat","tea"]]


Input: strs = [""]

Output: [[""]]


Input: strs = ["a"]

Output: [["a"]]


There are 2 approaches to this problem: One approach is to categorize by sorted string and the second approach is to categorize by count. 

Let's get the first approach first. 

I maintain a map where each key is a sorted string and each value is the list of string. Python is stored in a tuple, but I will go over Java for this particular question.

If we want to sort a string, make it to a char array first, then perform the Arrays.sort() operation. 


class Solution {

    public List<List<String>> groupAnagrams(String[] strs){

        if(strs.length == 0) return new ArrayList();

        Map<String, List> ans = new HashMap<String, List>();

        for (String s : strs) {

            char[] ca = s.toCharArray();

            Arrays.sort(ca);

            String key = String.valueOf(ca);

            if(!ans.containsKey(key)) ans.put(key, new ArrayList());

            ans.get(key).add(s);

        }

        return new ArrayList(ans.values());

    }

}


Now, I want to go over the alternative way, which is to categorize by count. The hashtable representer will be a string delimiter for each letter of the alphabet. This is a way to group the strings: 

"aab" has 2 a's, and 1 b, so there are 26 total entries in this delimiter, enumerated as follows:


#2#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0

I think this is 26 entries, not entirely sure though.

Anyways, here's the solution:


class Solution {

    public List<List<String>> groupAnagrams(String[] strs) {

        if(strs.length == 0) return new ArrayList();

        Map<String, List> ans = new HashMap<String, List>();

        int[] count = new int[26];

        for(String s : strs) {

            Arrays.fill(count, 0);

            for(char c : s.toCharArray()) count[c - 'a']++;

            StringBuilder sb = new StringBuilder("");

            for(int i = 0; i < 26; i++){

                 sb.append('#');

                 sb.append(count[i]);

            }

            String key = sb.toString();

            if (!ans.containsKey(key)) ans.put(key, new ArrayList());

            ans.get(key).add(s);

        }

        return new ArrayList(ans.values());

    }

}


Both complexities are O(NK) where N is the length of strs and K is the maximum of the length of strs.


Comments

Popular Posts