Day07 哈希表part02

第七天:哈希表part02

LC454四数相加II(未掌握

  1. 未掌握分析:考虑到了四层for循环的暴力解法,甚至很接近正解想到拆分为两组,但是没有继续下去
  2. 解题思路:四层for循环会超时,分为两组,分别为a+b和c+d,只需要a+b+c+d=0即可,时间复杂度降为O(n^2),并采用hashMap来提升查找效率
  3. 代码:
    在这里插入图片描述

LC383赎金信

在这里插入图片描述

LC15三数之和(未掌握

  1. 未掌握分析:
    • 采用确定一个元素,然后找两数之和等于-nums[i]的方法,但是问题在于去重
    • i的去重很好处理,直接if(i>0 && nums[i-1]==nums[i]) continue;
    • j的去重不好处理,如果是if(j>i+1 && nums[j-1]==nums[j]) continue;
      • 测试用例为[-2,0,1,1]时,i=0,j=3时,因为nums[2]==nums[3],会导致错过[-2,1,1]的结果
    • 并且已经是第三次看到这个题目了,仍然未想起双指针的想法,警醒!!!
  2. 错误代码:
    在这里插入图片描述
  3. 正确思路:使用双指针来处理,但是数组需要进行排序
    • 确定nums[i],定义双指针left和right,其中left = i+1,right = nums.length-1;
    • 当nums[i]+nums[left]+nums[right]>0,说明和大了,又因为数组是排序好的,因此right–
    • 当nums[i]+nums[left]+nums[right]<0,说明和小了,又因为数组是排序好的,因此left++
    • 剪枝操作:当nums[i]>0时,由于数据是排序的,后续的两数之后不可能会小于0,直接return result;
    • 去重操作:
      • i的去重:if(i>0 && nums[i-1]==nums[i]) continue;
      • left和right的去重:
        • while(left<right && nums[left]==nums[left+1]) left++;
        • while(left<right && nums[right]==nums[right-1]) right–;
  4. 代码:
    在这里插入图片描述

LC18四数之和(未掌握

  1. 解题思路:
    • 思想跟三数之和差不多,只不过是使用了两层for循环,然后使用双指针
  2. 剪枝操作:
    • 三数之和:当nums[i]>0时,由于数据是排序的,后续的两数之后不可能会小于0,直接return result;
    • 四数之和:
      • 三数之和中0是确定值,因此可使用上诉的剪枝操作,但是因为四数之和中target是不确定的,可能是负数,因此不能使用nums[i]>target。如target=-5,nums=[-4,-1,0,0]则会出错。
      • nums[i]>target && target>0
  3. 因为数据中存在超过int类型界限的数,所以sum要使用long类型,但是
    • 切记是long sum = (long)nums[i]+nums[j]+nums[left]+nums[right];
    • 而不是long sum = (long)(nums[i]+nums[j]+nums[left]+nums[right]);
    • 因为一个超出int界限就可以转换了,接下来的会自动转换,但是四个加起来已经超过了int界限就变成了其他的值再转换,失真了
  4. 代码:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值