LeetCode刷题笔记(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.

题意分析: 

给定一个字符串数组(数组没有特殊指明,应该可以为空集),请寻找anagrams组,说白了就是将相同字母组成各种不同顺序的组合放一起,然后用一个二维向量组返回结果。注:①所有的输入均为小写字母;②最终返回结果的顺序不重要。

解答如下:

方法一(哈希表嵌套集合法)

根据题意,可以先把每个字符串进行排序,然后创建一个hash_map(unordered_map型变量),其键为每个字符串排序后的结果,其值为一个set,用于存放(insert)排序前的结果。由于set的底层实现利用了平衡二叉树,所以集合元素都是按照顺序排好了的。

注:①hash_map(哈希表)是指unordered_map,对于map的底层实现还是平衡二叉树,所以map的到的结果也是有序的。

②由于set,map底层实现是平衡二叉树,所以他们的时间复杂度为O(logn),而unordered_set,unordered_map的底层实现是hash_map,所以他们的时间复杂度为O(1)。

class Solution{
public:
    vector<vector<string> > groupAnagrams( vector<string>& strs){
        vector<vector<string> > result;
        string tmp;        //这里不可以定义为vector,因为定义的set中装的是string
        unordered_map<string,multiset<string>> record;
        for (int i = 0; i < strs.size(); i++) {
            tmp = strs[i];
            sort(strs[i].begin(),strs[i].end());
            record[strs[i]].insert(tmp);  //map和set的插入操作
        }
        for (auto rec : record) {   //遍历hash map的所有元素
            vector<string> res (rec.second.begin(), rec.second.end()); //用hash map中每个元素的值(字符串集合),对向量res进行初始化。
            result.push_back(res);
        }
        return result;
    }
};

  提交后的结果如下:

方法二(优化方法一)

①方法一中系统自带的sort排序为改进的快排算法,时间复杂度为O(nlogn)。由于题目明确指出只有小写字母,故可以使用计数排序进一步加快算法的速度(从O(nlogn)降为O(n))。

②方法一未判断字符串数组为空集的情况。

③对方法一中两处for循环进行优化。

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> result;
        if (strs.empty()) {                      //判断字符串数组是否为空
            return result;
        }
        unordered_map<string, multiset<string>> record;
        for (string str : strs) {                //优化for循环
            string tmp = countSort(str);
            record[tmp].insert(str);
        }
        for (auto rec : record) {                //优化for循环
            vector<string> res(rec.second.begin(), rec.second.end());
            result.push_back(res);
        }
        return result;
    }

    string countSort(string s) {                 //计数排序
        vector<int> count(26, 0);
        for (int i = 0; i < s.length(); ++i) {
            ++count[s[i] - 'a'];
        }
        string res = "";
        for (int i = 0; i < 26; ++i) {
            while (count[i]--) {
                res += ('a' + i);
            }
        }
        return res;
    }
};

 提交后的结果如下:

日积月累,与君共进,增增小结,未完待续。      

猜你喜欢

转载自blog.csdn.net/Vensmallzeng/article/details/88084944