zoukankan      html  css  js  c++  java
  • [LeetCode]56. Group Anagrams变位词分组

    Given an array of strings, group anagrams together.

    For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"]
    Return:

    [
      ["ate", "eat","tea"],
      ["nat","tan"],
      ["bat"]
    ]

    Note:

    1. For the return value, each inner list's elements must follow the lexicographic order.
    2. All inputs will be in lower-case.

    Update (2015-08-09):
    The signature of the function had been updated to return list<list<string>> instead of list<string>, as suggested here. If you still see your function signature return alist<string>, please click the reload button to reset your code definition.

    Subscribe to see which companies asked this question

    解法1:前面已经做过题目验证两个字符串是不是互相成为变位词,因此一个简单的思路就是两层循环,判断每两对个词语是否互为变位词,时间复杂度大于O(n^2),会超时Time Limit Exceeded

    class Solution {
    public:
        vector<vector<string>> groupAnagrams(vector<string>& strs) {
            int n = strs.size();
            vector< vector<string> > res;
            vector<int> flag(n, 0);
            for (int i = 0; i < n; ++i)
            {
                if (flag[i] == 1) continue;
                vector<string> tmp = { strs[i] };
                flag[i] = 1;
                for (int j = i + 1; j < n; ++j)
                {
                    if (flag[j] == 1) continue;
                    if (isAnagram(strs[i], strs[j]))
                    {
                        tmp.push_back(strs[j]);
                        flag[j] = 1;
                    }
                }
                sort(tmp.begin(), tmp.end());
                res.push_back(tmp);
            }
            return res;
        }
    private:
        bool isAnagram(string s, string t) {
            int ss = s.size(), ts = t.size();
            if (ss != ts)  return false;
            vector<int> v1(26, 0), v2(26, 0);
            for (int i = 0; i < ss; ++i)
            {
                ++v1[s[i] - 'a'];
                ++v2[t[i] - 'a'];
            }
            for (int i = 0; i < 26; ++i)
                if (v1[i] != v2[i]) return false;
            return true;
        }
    };

    解法2:另一个想法是顺序扫描字符串序列,如果发现当前字符串不是以前任意字符串的变位词,则新建vector<string>加入到结果中,同时记录下当前字符串的模式,留待后面进行匹配。这样时间复杂度还是比较高,也会超时Time Limit Exceeded

    class Solution {
    public:
        vector<vector<string>> groupAnagrams(vector<string>& strs) {
            int n = strs.size();
            vector< vector<string> > res;
            vector< map<char, int> > pattSet;
            for (int i = 0; i < n; ++i)
            {
                map<char, int> patt;
                for (int j = 0; j < strs[i].size(); ++j)
                    ++patt[strs[i][j]];
                vector< map<char, int> >::iterator iter1 = find(pattSet.begin(), pattSet.end(), patt);
                if (iter1 == pattSet.end())
                {
                    res.push_back(vector<string>{strs[i]});
                    pattSet.push_back(patt);
                }
                else
                    res[iter1 - pattSet.begin()].push_back(strs[i]);
            }
            for (int i = 0; i < res.size(); ++i)
                sort(res[i].begin(), res[i].end());
            return res;
        }
    };

    解法3:将解法2的vector<map<char, int>>改进。只要将每个字符串排序就可以得知它们是不是互为变位词,因此模式可以存储为string类型,而对应的所有变位词在strs中的下标则存于vector中,因此设计Map为map<string, vector<int>>。

    class Solution {
    public:
        vector<vector<string>> groupAnagrams(vector<string>& strs) {
            int n = strs.size();
            vector< vector<string> > res;
            map<string, vector<int> > m;
            for (int i = 0; i < n; ++i)
            {
                string s = strs[i];
                sort(s.begin(), s.end());
                m[s].push_back(i);
            }
            for (map<string, vector<int> >::iterator iter = m.begin(); iter != m.end(); ++iter)
            {
                vector<string> tmp;
                for (int i = 0; i < iter->second.size(); ++i)
                    tmp.push_back(strs[iter->second[i]]);
                sort(tmp.begin(), tmp.end());
                res.push_back(tmp);
            }
            return res;
        }
    };
  • 相关阅读:
    Linux命令
    Java Script Closure(js闭包)-浅谈
    Java垃圾回收机制-概述
    五、面试准备-技术扩展
    四、面试准备-前端知识
    三、面试准备-框架知识
    二、面试准备-数据库知识
    SpringBoot多环境配置+自定义属性+随机数配置
    SpringBoot入门
    Vue入门
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4935127.html
Copyright © 2011-2022 走看看