LeetCode刷题--思路总结记录

热题100 - 49. 字母异位词分组

  • 链接:49. 字母异位词分组 - 力扣(LeetCode)
  • 思路:
    • 字母异位词的特征:字母相同,但排列不同的字符串 ==> 故对其排序后都一定是相同的(因为每种字母的个数都是相同的)
    • 对每个单词按各自的字母顺序排序,新形成的单词作为hash表的key,原单词作为value,最终可构建hash表如下:
      • ![[Pasted image 20231109110616.png]]
    • 如何返回hash.second答案?
      • 将hash.second按照key来分组,push进vector数组中
      • vector数组的每个元素,也是vector数组。
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        //map<排序后单词,同排序的原单词数组>
        unordered_map<string,vector<string>> strVec;

        //1.给每个单词,按重排序后进行分组
        for(auto const &str:strs) //②
        {
            //1.1 ktmp:重排序后的新单词,作为key
            string ktmp = str;
            sort(ktmp.begin(),ktmp.end());
            //1.2 把原单词分到自己的小组
            strVec[ktmp].emplace_back(str); //①
        }

        //2.把分组结果取出,合并到res中
        vector<vector<string>> res;
        for(auto const &v:strVec)
        {
            res.emplace_back(v.second);
        }
        return res;
    }
};
  • 优化:
    • emplace_back()push_back()的区别
      • 提交后查看相同思路但相对速度快一点的写法,看到采用emplace_back() 替代 push_back() ,于是二者进行对比了解
      • 二者区别在于底层实现的机制不同。
      • push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素)
      • emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
    • ② 或在auto时采用for (auto const &s : strs)也会快一些
    • ①和②的优化都是在于减少拷贝,所以会快一点

热题100 - 1. 两数之和

  • 链接:1. 两数之和 - 力扣(LeetCode)

  • 思路:

    • 将每个数字作为key,对应下标作为value存到hash表中;再二次遍历数组每个数字num,逐一找hash[target-num] ==> 因为题目表示一定有答案,且唯一 ==> 存在如下问题:
      • ① 两个相同的数字,第一个数字的下标会被第二个数字下标所覆盖
      • ② 遍历两次效率有问题
    • 故思考:由于题目表示一定有答案 ==> 于是采用边遍历,边找
      • 若找到了,就直接返回
      • 若没找到,就先存到hash表里,因为可能当前的数会被后面的数匹配上
  • 细节:

    • ①hash中找是否存在这个key值,不能根据key对应的value是否为0来找:因为在hash表里找不存在的key时,它的value也是0;容易和下标刚好为0的数混在一起 ==> 得用find
      • find()函数:会查找容器中是否存在特定值,如果不存在会指向末尾 end;
      • find返回的是指针,读取需要it->second;若根据key读value,则iVal[target-nums[i]]即可
      • 因为哈希表里存的是在i之前的数,所以找到了应先返回哈希表里找到数的下标
    • ③ 虽然题目表示有且仅有唯一解,但仍需return{}
    • ④ 从头枚举,没能匹配就存入表中
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //创建哈希表
        unordered_map<int,int> iVal;
        
        //从数组头的下标开始遍历,i标记的是目标值在nums里的下标
        for(int i=0;i<nums.size();i++)
        {
          auto it=iVal.find(target-nums[i]); //①
          if(it!=iVal.end())
          {
            return {iVal[target-nums[i]],i};
            //②或return {it->second,i};
		  }else{
			  iVal[nums[i]] = i;//④ 从头枚举,没能匹配就存入表中
		  }
        }
        return {};//③
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值