[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:
- For the return value, each inner list's elements must follow the lexicographic order.
- 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); } }