【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;
    }
};
 
 

 

posted @ 2019-01-05 16:06  wikiwen  阅读(183)  评论(0编辑  收藏  举报