代码随想录day6

242.有效的字母异位词

一开始想着构建两个hash表,但如果后面字符串长的可能会超时
这里借用数组构建hash表,主要思想是26个字母组成的数组统计出现次数

如果有出现次数为非0,则说明有问题,可以加以利用作为判断条件

 bool isAnagram(string s, string t) {
        int record[26] = {0};
        for(int i = 0; i < t.size(); i++)
        {
            record[t[i] - 'a']++;
        }

        for(int i = 0; i < s.size(); i++)
        {
            record[s[i] - 'a']--;
        }

        for(int i = 0; i < 26; i++)
        {
            if(record[i] != 0)
                return false;
        }

        return true;
        // unordered_map<char, int> mp;
        // unordered_map<char, int> mp2;
        // for(int i = 0; i < t.size(); i++)
        //     ++mp[t[i]];
        // for(int i = 0; i < s.size(); i++)
        //     ++mp2[s[i]];
        // return (mp2 == mp) ? true: false;
    }

49. 字母异位词分组

这里对乱序的子字符串先排序,排序后的结果是否一致可以作为分组的依据

同一组的异位词排序后结果应该是一致的,可以作为hash表的索引

    string getSortedStr(string str) {
        sort(str.begin(),str.end()); // 所有异位词按字典序排列后都相同
        return str;
    }
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> hash;
        for (string str : strs) {
            string strId = getSortedStr(str);
            hash[strId].push_back(str);
            // cout<<strId<<" "<<hash[strId].size()<<endl;
        }
        vector<vector<string>> groups;
        for (auto group : hash) {
            // cout<<group.first<<endl;
            groups.push_back(group.second);
        }
        return groups;
    }

438. 找到字符串中所有字母异位词

这里利用了字母出现次数的思想,很巧妙

    vector<int> findAnagrams(string s, string p) {
        int m = s.size(), n = p.size();
        if(m < n) return {};
        vector<int> hashTable(26);
        for(auto ch : p) ++hashTable[ch - 'a'];
        
        vector<int> ret;
        for(int l = 0, r = 0; r < m; ++r) {
            --hashTable[s[r] - 'a'];

            while(hashTable[s[r] - 'a'] < 0) {
                ++hashTable[s[l] - 'a'];
                ++l;
            }

            if(r - l + 1 == n) ret.push_back(l);
        }
        return ret;

异位词主要有两种做法,字母出现次数构建数组hash和先排序再hash

有限考虑字母出现次数,排序有可能超时

1. 两数之和

这里需要避免两次for循环,那就需要一个数据结构存储遍历过的值,来查找过去的值有没有能和当前值配对符合条件的。首先想到集合set,但这里还需要返回元素下标,所以用map。

 map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。

在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。

vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hashtable;
        for (int i = 0; i < nums.size(); ++i) {
            auto it = hashtable.find(target - nums[i]);
            if (it != hashtable.end()) {
                return {it->second, i};
            }
            hashtable[nums[i]] = i;
        }
        return {};
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值