【Leetcode】49. 字母异位词分组

题目描述

// 49. 字母异位词分组

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

题解

// 一开始会想到逐个字符比对,但是太低效率了。
// 既然会被分到一组的String都是组成字符相同的String,
// 那么这些组成字符相同的String,不管字符再怎么排列,
// 如果把所有字符排序,得到的排序String一定是相等的,
// 所以我们使用一个HashMap的key来保存这些排序好的String,对应的value来保存
// 需要被分到List<String>组的组号,拥有相同的排序String,说明其字符串属于同一个组。

// 把遍历到的String str排序好,在map中寻找是否存在这个key(排序后str),
// 如果存在这个key,就取出这个key对应的组号value,把str放进第value组中。
// 这样就实现了组成字符相同的String放到一个组中了。
// 
// 构建答案保存字符串组List<List<String>> res,构建HashMap<String, Integer> map,
// 定义创建小组的分组索引index,初始化为0。for循环遍历strs中字符串str,
// 将str转为char[],排序后再恢复为字符串形式,得到排序后的str,记为key。
// 条件判断key是否在map的key中,不在的话直接存入<key, index>,表示以后凡是
// 排序str等于这个key的,index组。之后index累加1,用作下一个组的组号。
// 
// 如果map中key已存在,说明str是属于第 map.get(key) 组的,把str存入
// res中第的 map.get(key) 组。循环结束,返回res。
// 
// 注意:String排序,要使用Arrays.sort(),就需要把String转为char[],排序好
// 再转回String。有人会想,为什么不直接把char[]作为key?因为HashMap中
// containsKey函数判断key对象相等,使用的是Object类中的equals方法,实际是判断
// 地址相等,而我们每次创建char[] temp都在new新对象,已经不是同一个引用了,
// 系统会认为我们遍历的str转换出的所有char[]都是不相等的,map.containsKey(key)
// 永远是false,循环就会一直执行if,不执行else,这就出错了。
// 而String包装类中的equals被重写了,是判断内容相等,我们就是要判断key的内容
// 相等,所以还需要将char[] temp转为String key。
// 
// 输入案例 ["eat", "tea", "tan", "ate", "nat", "bat"]
// HashMap最终的保存情况,{ ["aet", 0], ["ant", 1], ["abt", 2] }

// 执行用时:7 ms, 在所有 Java 提交中击败了96.01%的用户
// 内存消耗:41.4 MB, 在所有 Java 提交中击败了73.42%的用户
import java.util.HashMap;
import java.util.Arrays;
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
		List<List<String>> res = new ArrayList<>();
		HashMap<String, Integer> map = new HashMap<>();
		int index = 0;
		for (String str : strs) {
			char[] temp = str.toCharArray();
            Arrays.sort(temp);
            String key = String.valueOf(temp);

			if (!map.containsKey(key)) {
                map.put(key, index++);
				List<String> combination = new ArrayList<>();
				combination.add(str);
				res.add(combination);
			}
			else {  // map.containsKey(key)
                res.get(map.get(key)).add(str);
			}
		}
		return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锥栗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值