• 【LeetCode & 剑指offer刷题】字符串题14:242. Valid Anagram (变位词系列)


    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    242. Valid Anagram (变位词)

    Given two strings s and , write a function to determine if t is an anagram of s.
    Example 1:
    Input: s = "anagram", t = "nagaram"
    Output: true
    Example 2:
    Input: s = "rat", t = "car"
    Output: false
    Note:
    You may assume the string contains only lowercase alphabets.
    Follow up:
    What if the inputs contain unicode characters? How would you adapt your solution to such case?

     
    //问题:字谜/变位词(判断某个字符串是否可以组合成某一个单词,假设只有小写)
    /*
    方法一:排序之后看是否一样
    性能:O(nlogn) O(1)
    */
    /*using namespace std;
    #include <string>
    #include <algorithm>
    class Solution
    {
    public:
        bool isAnagram(string s, string t)
        {
            sort(s.begin(), s.end());
            sort(t.begin(), t.end());
            return (s==t);
           
        }
    };*/
            // if(s.find(t) != string::npos) return true; //查找是否有某个子串,不行,因为可能顺序不一样
            // else return false;
    /*
    方法二:统计表法(这里可以直接用数组统计)
    延伸:如果key值分布较散,比如包含unicode字符,可以考虑用hash表,
    性能:O(n) O(1)
    */
    using namespace std;
    #include <string>
    #include <algorithm>
    class Solution
    {
    public:
        bool isAnagram(string s, string t)
        {
            if(s.size() != t.size()) return false;
           
            int counter[26] = {0}; //26个小写英文字母
            for(int i = 0; i<s.size(); i++)
            {
                counter[s[i]-'a']++;//也可用两个统计表分别统计,最后比较两个统计表是否相等     
                counter[t[i]-'a']--;
            }
            for(int count:counter)
            {
                if(count != 0) return false;
            }
            return true;
           
        }
    };
     
     
     
     
    49. 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.
     
    //输出字谜组(这里字谜表示通过变序可以组成一个单词的字符串)
    //相关题目:Valid Anagram
    /*
    方法一:用hash表map实现,key--->value为string--->vector<string>
    如:"aer": ["are", "ear", "era"]
    O(nklogk),O(nk),n为strs的长度,K为strs里字符串的最大长度
    */
    #include <unordered_map>
    #include <string>
    class Solution
    {
    public:
        vector<vector<string>> groupAnagrams(vector<string>& strs)
        {
            unordered_map<string, vector<string>> mp;
            for(string s:strs)
            {
                string t = s;
                sort(t.begin(), t.end()); //key值,字谜单词排序后key值相同
                mp[t].push_back(s); //当前key值添加value
            }
           
            vector<vector<string>> res;
            for(auto& m:mp) //将map中value全部push到结果向量中
            {
                res.push_back(m.second); //用.second访问map中的键值
            }
            return res;
        }
    };
    /*
    方法二:用统计表法实现,用单词的统计表(可以用vector,长度为26)作为key值
    如:[2,1,0,0,...,0]: ["are", "ear", "era"]
    O(nk),O(nk),n为strs的长度,K为strs里字符串的最大长度
    general sort takes O(nlogn) time. In this problem, since the string only contains lower-case alphabets, we can write a sorting function using counting sort (O(n) time) to speed up the sorting process.
    */
    class Solution {
    public:
        vector<vector<string>> groupAnagrams(vector<string>& strs) {
            unordered_map<string, multiset<string>> mp;
            for (string s : strs) {
                string t = strSort(s);
                mp[t].insert(s);
            }
            vector<vector<string>> anagrams;
            for (auto m : mp) {
                vector<string> anagram(m.second.begin(), m.second.end());
                anagrams.push_back(anagram);
            }
            return anagrams;
        }
    private:
        string strSort(string& s) {
            int count[26] = {0}, n = s.length();
            for (int i = 0; i < n; i++)
                count[s[i] - 'a']++; //相当于计数排序
            int p = 0;
            string t(n, 'a');
            for (int j = 0; j < 26; j++) //将“直方图”摊开,j代表某个字母,count[j]代表该字母的个数
                for (int i = 0; i < count[j]; i++)
                    t[p++] += j;
            return t;
        }
    };
     
     
  • 相关阅读:
    USACO 3.1
    linux 逻辑卷管理 调整分区大小
    记录一下
    ADOX创建ACCESS数据库列名的数据类型
    使用jstack分析cpu消耗过高的问题
    fastadmin添加定时任务
    linux定时任务
    技术域
    IOS div上下滑动效果
    mysql根据时间统计数据语句
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10224923.html
Copyright © 2020-2023  润新知