leetcode-49-字母异位词分组(group anagrams)-java

题目及测试

package pid049;

import java.util.List;

/*字谜分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["natt","tatn"],
  ["bat"]
]

说明:

    所有输入均为小写字母。
    不考虑答案输出的顺序。





*/
public class main {
	
	public static void main(String[] args) {
		String[][] testTable1 ={
				{"eat", "tea", "tan", "ate", "nat", "bat"},
				{"eatt", "ttea"},
				{"erd", "tea"}
		};
		for(int i=0;i<testTable1.length;i++){
			test(testTable1[i]);
		}
		
			
		
	}
		 
	private static void test(String[] ito) {
		Solution solution = new Solution();
		int length=ito.length;
		for(int i=0;i<length;i++){			
			System.out.print( ito[i]+"  ");								
		}
		System.out.println();
		long begin = System.currentTimeMillis();
		List<List<String>> rtn=solution.groupAnagrams(ito);//执行程序
		long end = System.currentTimeMillis();		
		
		for(int i=0;i<rtn.size();i++){
			List<String> now=rtn.get(i);
			for(int j=0;j<now.size();j++){
				System.out.print( now.get(j)+"  ");
			}
			System.out.println();
		}
		
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

 

解法1(成功,826ms,超慢)

建立一个hashmap的列表,每个hashmap 以character为key,以integer为value
把每个字符串,每个字符的数量存入其中
然后将hashmap的equals方法,逐个比对后加入

package pid049;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
    int length=strs.length;
    if(length==0){
    	return null;
    }
    List<HashMap<Character, Integer>> source=new ArrayList<>();
    for(int i=0;i<length;i++){
    	HashMap<Character, Integer> now=new HashMap<>();
    	String nowStr=strs[i];
    	for(int j=0;j<nowStr.length();j++){
    		Character nowChar=nowStr.charAt(j);
    		if(now.containsKey(nowChar)){
    			now.put(nowChar, now.get(nowChar)+1);
    		}
    		else{
    			now.put(nowChar, 1);
    		}
    		
    	}
    	source.add(now);
    }
    List<List<String>> result=new ArrayList<>();
    List<String> sour=new ArrayList<>(Arrays.asList(strs));
    boolean[] hasStr=new boolean[length];
    for(int i=0;i<length;i++){
    	if(hasStr[i]==false){
    		List<String> nowResult=new ArrayList<>();
			nowResult.add(strs[i]);//入字符串
			hasStr[i]=true;
			for(int j=i+1;j<length;j++){
				if(hasStr[j]==false){
					if(source.get(i).equals(source.get(j))){
						nowResult.add(strs[j]);//入字符串
						hasStr[j]=true;
					}
				}
			}
			result.add(nowResult);
		}
    	
    	
    }
	
	
	return result;
    }
}

解法2(成功,22ms,很快)

 算法的关键是:如何将多个字母异位词定位到一个分类,即类似与hash(a)=hash(b)

这里的方法是,将字符串转为char数组,根据字母大小排序,再转为字符串,得到它的hashcode

建立一个hashmap<integer,integer>,key为字符串对应的hashcode,value为result里字符串对应的index

字符串最后加入index对应的那个list中去

    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<Integer, Integer> map=new HashMap<>();
        List<List<String>> result=new ArrayList<>();
        List<String> list;
        for(String string:strs){
        	int hash=getAnagramHash(string);
        	int index=0;
        	if(map.containsKey(hash)){
        		index=map.get(hash);
        	}else{
        		list=new ArrayList<>();
        		result.add(list);
        		index=result.size()-1;
        		map.put(hash, index);
        	}
        	list=result.get(index);
        	list.add(string);       	
        }  	
    	return result;
    }	
	
	/** 先将string安装字母顺序排列,得到排序后字符串的hashcode
	 * @param string
	 * @return
	 */
	public int getAnagramHash(String string){
		char[] chars=string.toCharArray();
		Arrays.sort(chars);
		return new String(chars).hashCode();
	}

解法3

其他的解法,不同的地方在于hash的方法不一样。

一种是,char数组排序后,生成的字符串作为hash的结果(不对这个生成的字符串hashcode)。

另一种是,用int[26]统计字符串的字母的个数,用字符串  1#2#3... 作为hash的结果,其中的1就代表a的个数,其他类似

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值