[LeetCode#49]Group Anagrams

Problem:

Given an array of strings, group anagrams together.

For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"]
Return:

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

 

Note:

  1. For the return value, each inner list's elements must follow the lexicographic order.
  2. All inputs will be in lower-case.

Wrong Solution 1:

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if (strs == null)
            throw new IllegalArgumentException("strs is null");
        List<List<String>> ret = new ArrayList<List<String>> ();
        if (strs.length == 0) {
            ret.add(new ArrayList<String> ());
            return ret;
        }
        Comparator<String> comp = new Comparator<String>() {
            @Override
            public int compare(String str1, String str2) {
                return str1.compareTo(str2);
            }
        };
        Arrays.sort(strs, comp);
        HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>> ();
        for (String str : strs) {
            String sorted_str = sortStr(str);
            if (map.containsKey(sorted_str)) {
                map.get(sorted_str).add(str);
            } else {
                ArrayList<String> item = new ArrayList<String> ();
                item.add(str);
                map.put(sorted_str, item);
            }
        }
        return ret;
    }
    
    
    private String sortStr(String str) {
        char[] char_array = str.toCharArray();
        Arrays.sort(char_array);
        return char_array.toString();
    }
}

Mistakes Analysis:

Mistake:
Input:
[""]
Output:
[]
Expected:
[[""]]

Analysis:
1. misunderstood "" with null. "" was also accounted as a string, it just has no character. But the string "" has a reference for it. 
[""] is a String array with only one element, the element is "" string. 
We must tackle it as a valid input. 
And there is a stupid bug in above solution. Not because the ability to handle "" string.
The "" would work a valid string to go through all the code. 
The problem for above solution is: I forget to add the newly created ArrayList<String> into ret set!!!
-----------------------------------------------------------
ArrayList<String> item = new ArrayList<String> ();
item.add(str);
map.put(sorted_str, item);

Fix:
ArrayList<String> item = new ArrayList<String> ();
item.add(str);
ret.add(item);
map.put(sorted_str, item);
-----------------------------------------------------------

2. There is also a block of extra code. The Arrays.sort() function acutally could handle the sort among strings, no need to implement any extra comparator. 

sort(Object[] a)
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements.
------------------------------------------------------------------------------
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
The natural ordering means the compareTo method defined in the class.
------------------------------------------------------------------------------
compareTo(String anotherString)
Compares two strings lexicographically.

Wrong Solution 2:

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if (strs == null)
            throw new IllegalArgumentException("strs is null");
        List<List<String>> ret = new ArrayList<List<String>> ();
        if (strs.length == 0) {
             ArrayList temp = new ArrayList<String> ();
             return ret;
        }
        Arrays.sort(strs);
        HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>> ();
        for (String str : strs) {
            String sorted_str = sortStr(str);
            if (map.containsKey(sorted_str)) {
                map.get(sorted_str).add(str);
            } else {
                ArrayList<String> item = new ArrayList<String> ();
                item.add(str);
                ret.add(item);
                map.put(sorted_str, item);
            }
        }
        return ret;
    }
    
    private String sortStr(String str) {
        char[] char_array = str.toCharArray();
        Arrays.sort(char_array);
        return char_array.toString();
    }
}

Mistakes Analysis:

Mistakes:
Input:
["",""]
Output:
[[""],[""]]
Expected:
[["",""]]

Analysis: 
I have mixed StringBuffer with char[]. 
For StringBuffer.toString(), it returns the string of the element in the array.
For char[].toString(), it returns the array's reference in String form, like : [C@31ccbefe.

Fix:
The char[] must be passed into a constructor of a new String.
return new String(char_array);

Solution:

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if (strs == null)
            throw new IllegalArgumentException("strs is null");
        List<List<String>> ret = new ArrayList<List<String>> ();
        if (strs.length == 0)
             return ret;
        Arrays.sort(strs);
        HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>> ();
        for (String str : strs) {
            String sorted_str = sortStr(str);
            if (map.containsKey(sorted_str)) {
                map.get(sorted_str).add(str);
            } else {
                ArrayList<String> item = new ArrayList<String> ();
                item.add(str);
                ret.add(item);
                map.put(sorted_str, item);
            }
        }
        return ret;
    }
    
    private String sortStr(String str) {
        char[] char_array = str.toCharArray();
        Arrays.sort(char_array);
        return new String(char_array);
    }
}

 

posted @ 2015-09-09 06:42  airforce  阅读(369)  评论(0编辑  收藏  举报