LeetCode 49: Group Anagrams
Title:
Given an array of strings, you can combine words with different letters. Alphabetic words refer to strings with the same letters but arranged differently.
Given an array of strings, group anagrams together.
Example:
Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]
Explain:
- All inputs are lowercase.
- Do not consider the order of the answer output.
Note:
- All inputs will be in lowercase.
- The order of your output does not matter.
Solutions:
The title requires that no matter how the letters are sorted, as long as the letters are the same, as long as the letters of all the words are arranged according to a certain rule, as long as the letters of each word are arranged according to the same rule and the strings are the same, then they are classified as one class
Sorting letters to solve problems:
Use the hash map {Key: Value} Key as the ordered string, Value as the array, store the words with the same letter as the Key, traverse each word and sort the letters, find out whether the sorted string exists in Keys, and use the hash map to reduce the complexity of the search operation time to O(1)
The solution logic is (in ascending order):
Input: ["eat", "tea", "tan", "ate", "nat", "bat"] Build hash map = {} Traverse the string array: First word: "eat" -- > AET " "aet" does not exist in the map. Establish the map {"aet": ["eat"]} Second word: "tea" -- > AET " "aet" exists in map, and its values {"aet": ["eat", "tea"]} are added The third word: "Tan" -- > ant " "Ant" does not exist in the map. Set up the map {"AET": ["eat", "tea"]; "ant": ["Tan"]} The fourth word: "ate" -- > AET " "aet" exists in map, and its values {"aet": ["eat", "tea", "ate"]; "ant": ["Tan"]} are added ...... map = {"aet" : [ "eat" , "tea" , "ate" ] ; "ant" : [ "tan" , "nat"] ; "abt" : [ "bat" ] } Returns an array of Values of the hash map: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]
Complexity:
- Time complexity: O(N*(K*logK)), where N is the length of strs, and K is the maximum length of string in strs. The complexity of traversing each string is O(N). The time complexity of sorting the letters in the string with the built-in sorting function is O(K*logK).
- Space complexity: O(N*K), the space occupied by data stored in the map.
Statistical word frequency problem solving:
This method can be further optimized and can omit the operation of string sorting.
Think about it carefully. A word is composed of at most 26 English letters. Can't you also create a hash map? For example:
For the word "aeat": Establish hash map {'a': 2; 'e': 1; t: 1}
Key is the word that appears, and the frequency that value appears. It is obviously more complicated to traverse each key to determine whether the letters are equal, and then to determine whether the occurrence times are equal.
The frequency of each letter can be formed into consecutive characters:
Frequency of a-z in each letter: [2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0] Composition string: "200010000000000000000001000000"
Just determine whether the letter frequency string of each word is the same.
For word frequency, it can also be optimized. The number of letters is fixed at 26, and an array with length of 26 is directly established. Its index represents 26 letter bits. It traverses the letters in the word. Each time the letters appear, the element value representing the letter in the array is increased by 1.
This avoids sorting operations
Sorting letters to solve problems:
Java:
class Solution { public List<List<String>> groupAnagrams(String[] strs) { if(strs.length==0) return new ArrayList<>(); Map<String, List<String>> map = new HashMap<>();//Establish a mapping relationship for (String s : strs) {//Traverse the string array char[] chs = s.toCharArray();//Convert to character Arrays.sort(chs);//Sort string letters String key = String.valueOf(chs);//Convert to string if(!map.containsKey(key)) map.put(key, new ArrayList<>());//If the key does not exist, create a new mapping relationship map.get(key).add(s);//Add the array of the corresponding Value } return new ArrayList(map.values());//Returns an array of Values } }
Python:
class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: ans = collections.defaultdict(list) # Establish a mapping relationship for s in strs: # Traverse the string array ans[tuple(sorted(s))].append(s) # sorted(s): sort string letters and add the array of their corresponding values return ans.values() # Returns an array of Values
Statistical word frequency problem solving:
Java:
class Solution { public List<List<String>> groupAnagrams(String[] strs) { if (strs.length == 0) return new ArrayList<>(); Map<String, List<String>> map = new HashMap<>();// Establish a mapping relationship for (String s : strs) {//Traverse the string array int[] count = new int[26];//Establish a 26 letter mapping for (char c : s.toCharArray()) count[c - 'a']++;//Traverse word string count the frequency of each letter String key = Arrays.toString(count);//Convert to string if (!map.containsKey(key)) map.put(key, new ArrayList<>());//If the key does not exist, create a new mapping relationship map.get(key).add(s);//Add the array of the corresponding Value } return new ArrayList(map.values());//Returns an array of Values } }
Python:
class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: ans = collections.defaultdict(list)# Establish a mapping relationship for s in strs: # Traverse the string array count = [0] * 26 # Establish a 26 letter mapping for c in s: # Traversal character string each letter count[ord(c) - 97] += 1 # Frequency of each letter (element value) plus 1 ans[tuple(count)].append(s) # Add the array of the corresponding Value return ans.values() # Returns an array of Values
Welcome to wechat.com.cn: love to write Bug