?我一開始的思路就是用1個hashmap<Integer,List<String>>,Integer存的的是字符串所有字母ASCLL值的和,List里面放異位字符串,但是不是異位的字符串的ascll值也可能相同比如acd和abe,所以這個hashmap只能降低一點時間復雜度我還是要寫一個方法來判斷是不是異位字符串,就在我寫的時候我突然意識到,這樣的話hashmap的key會重復啊,我必須得想辦法找到一個key使得異位字符串有相同的key其他沒有。百思不得其解,最后還是點開了題解,剛點開,映入眼簾的”字母排序“四個字讓我恍然大悟,我立馬關掉題解自己寫。
異位字符串把字母排完之后就是一樣的啊,拿這個排完序的字符串作為key就好了啊,最簡單的排序當然是冒泡了,但是我交換兩個字母順序的時候我寫的str.charAt(i)=str.charAt(j),這行代碼有問題,好像不能這樣賦值,只能用雙等號比較,然后就寫了一個很屎的字符串排序,知道通過排序字母就知道如何解題了,以下是我的屎代碼:
class Solution {public List<List<String>> groupAnagrams(String[] strs) {List<List<String>> ans = new ArrayList<List<String>>();int n = strs.length;HashMap<String,List<String>> map = new HashMap<>();for(int i=0;i<n;i++){String strSort = strSort(strs[i]);if(map.containsKey(strSort)){map.get(strSort).add(strs[i]);}else{List value = new ArrayList<String>();value.add(strs[i]);map.put(strSort,value);}}for (String key:map.keySet()) {ans.add(map.get(key));}return ans;}public String strSort(String str){int n = str.length();char[] c = new char[n];for(int i=0;i<n;i++){c[i] = str.charAt(i);}for(int i=0;i<n;i++){for(int j = i+1;j<n;j++){if(c[i] > c[j]){char tmp = c[i];c[i] = c[j];c[j] = tmp;}}}String s = new String();for(int i=0;i<n;i++){s+=c[i];}return s;}
}
看了下題解的代碼,太牛了,很簡潔,他都沒自己排序
class Solution {public List<List<String>> groupAnagrams(String[] strs) {Map<String, List<String>> map = new HashMap<String, List<String>>();for (String str : strs) {char[] array = str.toCharArray();Arrays.sort(array);String key = new String(array);List<String> list = map.getOrDefault(key, new ArrayList<String>());list.add(str);map.put(key, list);}return new ArrayList<List<String>>(map.values());}
}
先用toArray()方法把一個字符串變成字符串數組,然后用Arrays.sort()方法把字符串數組排序,然后通過傳入一個字符串數組參數的構造方法創建這個排好了序的字符串,唉,我也是按照這三步寫的,但是tmd我全是自己寫的,這說明我對一些類的常用方法根本不熟悉。后面他沒有進行key的判斷,而是通過調用map.getOrDefault,其實原理一樣,map.getOrDefault也是先看有沒有這個key,有就拿出這個value,沒有就返回設置的默認值,這里的默認值是新建一個list,后面就add,put。
題解還有一種不排序的方法,就是統計字母的頻次,然后把頻次的數字轉成char加起來就是一個String,然后把這個String作為key,例如leetcode的key就是”00113000000100100001000000“,這樣異位字符串的key也是相同的。