LeetCode 49 字母异位词分组

语法总结

  1. unorder_map构造时,key会用到hash,不是标准库类型需要自定义hash函数,array<int, nums>不在默认中吗?
  2. push_back( )、insert( )、emplace_back( )区别?
  3. 声明std::array时需要声明长度,语法为array<int, 26> flag、赋值全为0、权威’a’、 fill函数(fill函数是否都可以用?)。
  4. map的遍历、赋值方式、 map[key].emplace_back(str) (太牛了);

map的遍历方式 1

for(const auto& pair : map){
	cout << "key: " << pair->first << "val: " << pair->second << endl;
}

map的遍历方式 2

for(const auto& i){
	cout << "key: " << pair->first << "val: " << pair->second << endl;
}
  1. array<char, n> 转string时,用到了string的构造函数,需要array<char, n>.data()和array<char, n>.length(), 没有length()会报错
    // Char 20: AddressSanitizer: stack-buffer-overflow on address 0x7f8e44d000da at pc 0x557b458bc4d9 bp 0x7ffc2573b0f0 sp 0x7ffc2573a8b8
    why?
  2. int 和 char 的相互转换,可以直接转换,int 10 -> char 变成ASC码为10的char字符。
  3. sort()的使用,sort()对任何容器都可以用吗?map啥的等非链式结构。

思路归纳

模式识别:一旦需要根据特征进行归类,就应该使用散列表。该种特征作为散列表的key。

时间复杂度太高… 高在哪里?

class Solution {
public:
    void Myhash(const string &s, array<int, 26> &flag){
        int temp;
        for(int k = 0; k < s.length(); k++){
            temp = s[k] - 'a';
            flag[temp]++;
        }
    }

    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        array<int, 26> flag = {0};
        array<int, 26> current_flag = {0};
        vector<vector<string>> result;

        for(int i = 0; i < strs.size(); i++){
            //遍历strs中的每个string,判断strs[i]是否属于某个已存在的数组
            bool a = true;
            Myhash(strs[i], current_flag);
            for(int j = 0; j < result.size(); j++){
                Myhash(result[j][0], flag);
                if(current_flag == flag){
                    // 如果strs[i]属于已存在的数组,直接将它push_back
                    result[j].push_back(strs[i]);
                    a = false;
                }
                flag = {0};
            }
                // 如果strs[i]不属于已存在的数组,则新建一个vector<string>对象,并插入result中
                // 初始化时还必须有长度1 ....
            if(a){
                vector<string> new_group(1, strs[i]);
                result.push_back(new_group);
            }
            current_flag = {0};
        }
        return result;
    }
};

正确写法 1

使用排序后的string元素作为key

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs){
        unordered_map<string, vector<string>> map;
        for(string str : strs){
            string key = str;
            sort(key.begin(), key.end());
            // 这一句话完成了两项赋值
            // 还能这样写woc...
            // 如果分开了先对map赋值,再对map中val vec<string>复制...
            map[key].emplace_back(str);
        }
        vector<vector<string>> ans;
        // 新版本for循环遍历map
        // pair的基基本用法。
        for(const auto& pair : map){
            ans.emplace_back(pair.second);
        }
        return ans;
    }
};

正确写法 2

使用记录string元素中出字母次数的长度为26的数组作为key

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs){
        // 这种写法,用array<int, 26>当key,但是由于unordered_map,没有定义与其有关的hash函数,所以直接写会编译错误
        // 两种解决方法:
        // 1. 跟官方标准答案一样,自定义一个和array<int, 26>有关的hash。
        // 2. 跟下面的答案一样,声明key为string类型,在为map插入key时,将array<int, 26>转换成string
        // unordered_map<array<int, 26>, vector<string>> map;
        unordered_map<string, vector<string>> map;
        
        for(string str : strs){
            // string key = str;
            // sort(key.begin(), key.end());
            // 这一句话完成了两项赋值
            // 还能这样写woc...
            // 如果分开了先对map赋值,再对map中val vec<string>复制...
            // map[key].emplace_back(str);

            array<char, 26> count = {0};
            // fill(count.begin(), count.end(), 'a');
            for(int i = 0; i < str.length(); i++){
                count[str[i] - 'a']++;
            }

            string count_str(count.data(), count.size());
            // string count_str(count.data());
            // array<char> 转 string 的时候要跟上 array<char>.size().
            // Char 20: AddressSanitizer: stack-buffer-overflow on address 0x7f8e44d000da at pc 0x557b458bc4d9 bp 0x7ffc2573b0f0 sp 0x7ffc2573a8b8
            map[count_str].emplace_back(str);
        }
        vector<vector<string>> ans;
        // 新版本for循环遍历map
        // pair的基基本用法。
        for(const auto& pair : map){
            ans.emplace_back(pair.second);
        }
        return ans;
    }
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值