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

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10224923.html