LeetCode OJ:Group Anagrams

本文探讨了一种改进的Anagrams分组算法实现方案,并对比分析了两种不同思路的执行效率。通过采用哈希表存储排序后的字符串作为键值,实现了高效查找与分组,显著提升了算法性能。

题目:
这里写图片描述


我的代码:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {

        vector<string> list;
        vector<vector<string>> group_list;
        vector<string>::size_type i, j, len;
        string::size_type size, count, k, sum_count;

        len = strs.size();
        sort(strs.begin(), strs.end());

        for (i = 0; i < len; i++)
        {
            list.clear();
            list.push_back(strs[i]);    //将原先字符串压入
            if (strs[i].empty()){
                size = len;
            }
            else
            {
                size = strs[i].size();  //计算该字符串的长度
            }


            count = 1;                  //同元素的字符串个数,为1表示将当前字符串计算在内
            for (j = i + 1; j < len; j++)
            {

                    if (strs[j].find_first_not_of(strs[i]) == string::npos || strs[j] == strs[i])   //表明两字符串同元素
                    {

                        list.push_back(strs[j]);
                        strs[j].swap(strs[i + 1]);  //将坐标为j的元素与坐标为i+1的元素互换,可以加快循环进度
                        i++;        //上一步内容互换位置后,则下一个元素无需再次比较了
                        count++;    //含相同元素的字符串个数加1
                    }
            }//for_j
            //sort(list.begin(), list.end());   //将list中的字符从小到大排序
            group_list.push_back(list);     //将有相同元素构成的一组字符串压入到group_list中
        }//for_i

        //sort(group_list.begin(), group_list.end());
        return group_list;
    }
};

结果:
这里写图片描述


我的思路:

  • 因为之前做过一道名为single Number II的题,感觉有点类似,所以我也采用了相同的比较思路,但结果却超时了。后来发现前者比较时,只需进行3次比较就可退出一次循环了。而这题的思路是必须将一次循环遍历完,其结果当然是循环时间大大增加。
  • 由于本人太渣想不到更好的思路,所以参考了别人优秀的代码:http://blog.youkuaiyun.com/guang09080908/article/details/47976481

参考代码如下:

vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> hashMap;
        for(auto &v : strs) {
            string tmp(v);
            sort(tmp.begin(), tmp.end());
            hashMap[tmp].push_back(v);
        }
        vector<vector<string>> result(hashMap.size());
        int k = 0;
        for(auto it = hashMap.begin(); it != hashMap.end(); ++it, ++k) {
            result[k].swap(it->second);
            sort(result[k].begin(), result[k].end());
        }
        return result;
    }

我的理解与学习:


  1. 在leetcode上提交该博主的代码,发现运行时间非常短,才60ms。这说明该代码执行效率高,算法思路值得学习和借鉴。

  2. string tmp(v);
    sort(tmp.begin(), tmp.end());

    在我第一版的代码中,我与作者有相同的想法,即先将strs中的字符串排序,方便后续查找。但是没有想过将这重排后的字符串作为键值查找。

  3. for(auto &v : strs) 第一次见到这种写法,百度发现这是c++11中新加入的语法,可参考:
    http://www.cnblogs.com/TianFang/archive/2013/01/25/2876099.html
    确实孤陋寡闻了,不过正好学习了,的确比长长的iterator抒写来的方便。

  4. 代码中运用了unordered_map、以前只用过map,汗!,于是百度了下 unordered_map 与map之前的区别,先简要总结如下:

    a):库不同。STL::map、Boost::unordered_map

    b):map内部的元素是有序排列的,二unordered_map是无序的。

    c):stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。

    d):map的用法:
    #include<map>
    using namespace std;

    unordered_map 的用法:
    #include <unordered_map>
    using std::unordered_map;

  5. 这其中的知识点又涉及到hash表和红黑树需要学习,继续fighting~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值