leetcode题目 49. 字母异位词分组

题目

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

示例:

输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

说明

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

思路

思路很简单,遍历输入中的每个词,判断它是否属于某一类已知的异位词,如果是,则和已知的异位词放入一个List,如果不是,则新建一个List放入。

异位词的判断:
(1)遇到一个词,我们先将其转换为char数组,然后进行排序再转回String类型,以此作为key值,我们维护一个保存不重复key值的HashMap容器,value则是一个List类型,用来放异位词。每当遍历到的key值不在容器中时,我们put一个key进去,反正我们将当前字符串add到对应的List里面。
(2)利用HaspMap统计字符串的词频,词频相同则为异位词,但这种容易超时。

代码1

public class problem49_2 {
	public List<List<String>> groupAnagrams(String[] strs) {
		//特判
		if (strs.length == 0)
			return new ArrayList();
		
		Map<String, List> ans = new HashMap<String, List>();
		for (String s : strs) {
			char[] ca = s.toCharArray();
			Arrays.sort(ca);
			String key = String.valueOf(ca);
//			String key = new String(ca);
			if (!ans.containsKey(key))
				ans.put(key, new ArrayList());
			ans.get(key).add(s);
		}
//		System.out.println(ans.values().getClass().toString());
		return new ArrayList(ans.values());
	}
	public static void main(String[] args) {
		problem49_2 pro = new problem49_2();
		String[] strs = { "eat", "tea", "tan", "ate", "nat", "bat" };
		List<List<String>> res = pro.groupAnagrams(strs);
		for (int i = 0; i < res.size(); i++) {
			for (int j = 0; j < res.get(i).size(); j++) {
				System.out.print(res.get(i).get(j) + " ");
			}
			System.out.println();
		}
	}
}

代码2

public class problem49 {
	public List<List<String>> groupAnagrams(String[] strs) {
		List<List<String>> res = new ArrayList<List<String>>();

		// 遍历每个字符串输出
		for (int i = 0; i < strs.length; i++) {
			//是否跳过当前外层循环标计
			boolean jump = false;
			for (int j = 0; j < res.size(); j++) {
				// 判断当前字符串是否属于以及出现过的某一类异位词
				// System.out.println(strs[i]+" "+res.get(j).get(0));
				if (isEqual(strs[i], res.get(j).get(0))) {
					res.get(j).add(strs[i]);
					//跳过当前循环
					jump = true;
					break;
				}
			}
			if (jump)
				continue;

			// 新的异位词新开一个List存放,并进行添加
			res.add(new ArrayList<String>());
			res.get(res.size() - 1).add(strs[i]);
		}

		return res;
	}

	// 判断两个字符串的组成是否相同
	public boolean isEqual(String str1, String str2) {
		if (str1.length() != str2.length())
			return false;

		HashMap<String, Integer> map = new HashMap<>();

		// 统计str1各字母出现的频率
		for (int i = 0; i < str1.length(); i++) {
			if (map.containsKey(str1.charAt(i) + "")) {
				int num = map.get(str1.charAt(i) + "");
				map.put(str1.charAt(i) + "", num + 1);
			} else {
				map.put(str1.charAt(i) + "", 1);
			}
		}

		// printhash(map);

		// 根据str2出现的字母递减频率值
		for (int i = 0; i < str2.length(); i++) {
			if (map.containsKey(str2.charAt(i) + "")) {
				int num = map.get(str2.charAt(i) + "");
				map.put(str2.charAt(i) + "", num - 1);

				// 若有频率递减为负,则返回false
				if (num - 1 < 0)
					return false;
			} else {
				// System.out.println("test");
				return false;
			}
		}

		return true;
	}

	// 打印hash便于调试
	public void printhash(HashMap<String, Integer> map) {
		for (Entry<String, Integer> entry : map.entrySet()) {
			String key = entry.getKey();
			int value = entry.getValue();
			System.out.println(key + "," + value);
		}
	}

	public static void main(String[] args) {
		problem49 pro = new problem49();
		String[] strs = { "eat", "tea", "tan", "ate", "nat", "bat" };
		List<List<String>> res = pro.groupAnagrams(strs);
		for (int i = 0; i < res.size(); i++) {
			for (int j = 0; j < res.get(i).size(); j++) {
				System.out.print(res.get(i).get(j) + " ");
			}
			System.out.println();
		}

		// System.out.println(pro.isEqual("eat", "bat"));
	}
}

发布了31 篇原创文章 · 获赞 0 · 访问量 329

猜你喜欢

转载自blog.csdn.net/qq_36360463/article/details/104196637
今日推荐