问题描述

https://leetcode.com/problems/anagrams/#/description

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: All inputs will be in lower-case.

单词分组,将由相同字母组成的单词分到一组

算法分析

本题最主要的问题是如何比对两个单词时相同的

单词排序法

将单词里的字母进行排序,这样只要字母组合相同,不同单词排序后组成的新单词都相同。如:"eat"排序后变为"aet""tea"排序后也变为"aet"

参考自Share my short JAVA solution

素数替代法

使用26个素数分别表示26个小写字母,这样可以实现一个单词可以由多个素数的乘积表示,由于素数的特性,不同的单词计算出来的结果必不相同,从而一个单词可以由一个素数表示,在比对单词时,可极大减小运算量。

参考自:Java beat 100%!!! use prime number

代码

public class Solution {
		
		/**
		 * 单词分组,将由相同字母组成的单词分到一组
		 * 字母排序算法:
		 * 将单词里的字母进行排序,这样只要字母组合相同,不同单词排序后组成的新单词都相同。
		 * @param strs
		 * @return
		 */
	    public List<List<String>> groupAnagrams1(String[] strs) {
	        Map<String, List<String>> map = new HashMap<>();
	        for(String str:strs) {
	        	char[] letters = str.toCharArray();
	        	Arrays.sort(letters);
	        	String new_str = String.valueOf(letters);
	        	if(!map.containsKey(new_str)) {
	        		map.put(new_str, new ArrayList<>());
	        	}
	        	map.get(new_str).add(str);
	        }
	        return new ArrayList<List<String>>(map.values());
	    }
	    
	    /**
	     * 素数求解算法:
	     * 使用26个素数分别表示26个小写字母,这样可以实现一个单词可以由多个素数的乘积表示,由于素数的特性,不同的单词计算出来的结果必不相同,从而一个单词可以由一个素数表示,
	     * 在比对单词时,可极大减小运算量。
	     * @param strs
	     * @return
	     */
	    public List<List<String>> groupAnagrams(String[] strs) {
	    	int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};
	    	Map<Integer, List<String>> map = new HashMap<>();
	    	for(String str:strs) {
	    		int k = 1;
	    		for(char ch:str.toCharArray()) {
	    			k *= primes[ch-'a'];
	    		}
	    		if(!map.containsKey(k)) {
	    			map.put(k, new ArrayList<>());
	    		}
	    		map.get(k).add(str);
	    	}
	    	return new ArrayList<List<String>>(map.values());
	    }
	    
}

LeetCode解题源码:https://github.com/zgljl2012/leetcode-java