LeetCode 30天挑战 Day-6

LeetCode 30 days Challenge - Day 6

本系列将对LeetCode新推出的30天算法挑战进行总结记录,旨在记录学习成果、方便未来查阅,同时望为广大网友提供帮助。


Group Anagrams

Given an array of strings, group anagrams together.

Example:

Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

Note:

  • All inputs will be in lowercase.
  • The order of your output does not matter.

Solution

题目要求分析:给定一个字符串数组,将其中由相同字母组成的字符串归类到一起。

解法:

为判断是否由相同字母组成,有两种方法:

  1. 对每个字符串进行排序,排序后相同的即为同组。
  2. 对每个字符串统计字母出现的次数,次数相同的即为同组。

本题如果调用sort()函数来实现第一个方法,复杂度则为O(KlogK)级别,但由于字母是有限且连续的,不妨考虑使用桶排序的方案,这样可以将复杂度降为O(K)(K为最长字符串长度)。

第二种方法复杂度同为O(K),本文采用第一种方法。

在知道如何判断后,考虑如何进行归类,作者使用的是unordered_map哈希结构进行归类,即:

  1. 建立一个由字符串到列表的映射:unordered_map<string, vector<string>> m;

  2. 对题目给出的数组,遍历之,将每个字符串元素进行桶排序,并且将结果作为映射的键,将原字符串加入该键对应的列表中:for (string s : strs) m[BucketSort(s)].push_back(s);

  3. 遍历m,将结果加入res即可:for (auto &v : m) res.push_back(v.second);

    (此处操作可以参考“对unordered_map进行遍历”)


// 桶排序
string BucketSort(string s) {
    string res;
    vector<int> bucket(26, 0);
    for (char c : s) bucket[c - 'a']++;
    for (int i = 0; i<bucket.size(); i++) while(bucket[i]--) {
        res += 'a' + i;
    }
    return res;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
    vector<vector<string>> res;
    unordered_map<string, vector<string>> m;
    for (string s : strs) m[BucketSort(s)].push_back(s);
    for (auto &v : m) res.push_back(v.second);
    return res;
}

传送门:Group Anagrams

2020/4 Karl

发布了30 篇原创文章 · 获赞 7 · 访问量 4435

猜你喜欢

转载自blog.csdn.net/weixin_40005329/article/details/105347410