LC 49.字母异位词分组

7 篇文章 0 订阅
6 篇文章 0 订阅

49.字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

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

示例 2:

输入: strs = [""]
输出: [[“”]]

示例 3:

输入: strs = ["a"]
输出: [[“a”]]

提示:

  • 1 ≤ s t r s . l e n g t h ≤ 1 0 4 1 \leq strs.length \leq 10^4 1strs.length104
  • 0 ≤ s t r s [ i ] . l e n g t h ≤ 100 0 \leq strs[i].length \leq 100 0strs[i].length100
  • strs[i] 仅包含小写字母

解法一(HashMap+排序)

思路分析:

  1. 对于 满足 字符串中的字符 按字母顺序排序后的 字符串相同的 字符串为一组,因此我们可以使用哈希表来进行保存

  2. 若对于一个字符串str,将其按照字母顺序重新排序后的字符串string,其在哈希表中出现过,则将str保存到哈希表中对应的列表中

  3. 若没有出现过,则需要创建新的字符串列表,并进行保存

  4. 遍历完字符串数组strs时,则完成了分组

实现代码如下:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 哈希表 统计字母异位词 出现的 字符串
        HashMap<String, List<String>> hashString = new HashMap<>();
        for (String str : strs) {    // 遍历数组strs
            char[] charArray = str.toCharArray();    // 将字符串转化为字符数组
            Arrays.sort(charArray);        // 对字符数组进行排序
            String string = Arrays.toString(charArray);    // 将排序好的字符数组转化为字符串
            List<String> stringList;    // 保存 相互为字母异位词的 字符串
            if (hashString.containsKey(string)) {    // 若哈希表中已存在该种字母异位词
                stringList = hashString.get(string);    // 则将保存列表返回
            } else {
                stringList = new ArrayList<>();        // 否则创建新列表
            }
            stringList.add(str);    // 将该字符串保存到对应的 字母异位词列表中
            hashString.put(string, stringList); // 并保存到哈希表
        }
        return new ArrayList<>(hashString.values());    // 将哈希表中的结果返回
    }
}

提交结果如下:

解答成功:
    执行耗时:9 ms,击败了30.66% 的Java用户
    内存消耗:46.4 MB,击败了8.04% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n ⋅ ( m l o g m + 2 m ) ) O(n \cdot (mlog^m+2m)) O(n(mlogm+2m)),其中,m为每个字符串的长度,排序花费 O ( m l o g m ) O(mlog^m) O(mlogm),将其转化为字符数组和重新转化为字符串花费 O ( 2 m ) O(2m) O(2m),n指的是字符串数组strs的长度

  • 空间复杂度: O ( n ⋅ m ) O(n \cdot m) O(nm)

解法二(HashMap+计数)

思路分析:

  1. 对于属于同一组字符异位词,除了按照规定顺序排序之后,可作为标识之外,还可以对其含有的字符进行计数,然后将其包含的字符和数目合并为一个标识字符串

  2. 如此,即可作为map的关键值

实现代码如下:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 哈希表 统计字母异位词 出现的 字符串
        HashMap<String, List<String>> hashString = new HashMap<>();
        for (String str : strs) {    // 遍历数组strs
            // 获取字符统计结果字符串
            String recordsByString = getRecordsByString(str);
            List<String> strsList = hashString.getOrDefault(recordsByString, new ArrayList<>());
            strsList.add(str);    // 将其添加到哈希表的值中
            hashString.put(recordsByString, strsList);
        }
        return new ArrayList<>(hashString.values());    // 将哈希表中的结果返回
    }
    // 对字符串出现的字符及数量进行统计
    // 将统计的字符 及其数目 拼接成字符串返回
    public String getRecordsByString(String str) {
        int[] records = new int[26];
        int len = str.length();
        for (int i = 0; i < len; ++i) {
            records[ str.charAt(i) - 'a' ] ++;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 26; ++i) {
            if (records[i] != 0) {
                sb.append(i+'a');
                sb.append(records[i]);
            }
        }
        return sb.toString();
    }
}

提交结果如下:

解答成功:
    执行耗时:9 ms,击败了30.66% 的Java用户
    内存消耗:46 MB,击败了19.57% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n ( k + ∣ Σ ∣ ) ) O(n(k+|Σ|)) O(n(k+∣Σ∣)),n为数组strs的长度,k是strs中字符的最大长度, ∣ Σ ∣ = 26 |Σ|=26 ∣Σ∣=26,遍历每个字符串时,还需要遍历一遍统计数组,其长度为26

  • 空间复杂度: O ( n ( k + ∣ Σ ∣ ) ) O(n(k+|Σ|)) O(n(k+∣Σ∣)),需要用哈希表来存储,n为数组strs长度,k则是字符串的长度,此外还有生成的哈希表的键

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值