day07_四数相加2_赎金信_三数之和_四数之和_总结

力扣454.四数相加2

题目链接:https://leetcode.cn/problems/4sum-ii/

思路

1.计算数组A每个元素和数组B中每个元素的和,和出现的次数。

2.定义一个map,key值为a+b,value值为a+b出现的次数。

3.计算数组C每个元素和数组D中每个元素的和,记为temp。从map中找是否存在0-temp,找到了就返回key值为(0-temp)时对应的value值。

自己实现

看了题解想清楚了上述几个问题,自己写出了代码,还挺开心的。

完整代码

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer,Integer> map=new HashMap<>();
        int res=0;
        for(int i=0;i<nums1.length;i++){
            for(int j=0;j<nums2.length;j++){
                int temp1=nums1[i]+nums2[j];
                if(!map.containsKey(temp1)){
                    map.put(temp1,1);
                }else{
                    map.put(temp1,map.get(temp1)+1);
                }
            }
        }
        for(int i=0;i<nums3.length;i++){
            for(int j=0;j<nums4.length;j++){
                int temp2=nums3[i]+nums4[j];
                if(map.containsKey(0-temp2)){
                    res+=(map.get(0-temp2));
                }
            }
        }
        return res;
    }
}

力扣383.赎金信

题目链接:https://leetcode.cn/problems/ransom-note/

思路

本题和有效的字母异位词一样的思路。唯一需要注意的点就是:例如,ransomNote=‘aa’,magazine=‘aab’,应该返回的是true。所以最后遍历res的判断条件要改改,只要字母数大于等于零就是true。

自己写出来的,耶!

完整代码

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] res=new int[26];
        for(int i=0;i<ransomNote.length();i++){
            res[ransomNote.charAt(i)-'a']--;
        }
        for(int i=0;i<magazine.length();i++){
            res[magazine.charAt(i)-'a']++;
        }
        for(int count:res){
            if(count<0) return false;
        }
        return true;
    }
}

力扣15.三数之和

题目链接:https://leetcode.cn/problems/3sum/

思路

1.将数组排序,遍历数组元素,并让left=i+1,right为数组末尾元素。当i+left+right<0时,说明和太小,需要增大left;当i+left+right>0时,说明和太大,需要减小right。直至left和right相遇。

2.在遍历数组元素即i时,我们要考虑去重。例如(-1,-1,2),若写成

	if(nums[i]==nums[i+1]){
		continue;
	}

就把三元组内有重复元素的情况去掉了。然而我们实际上是允许三元组内有重复元素的,不被允许的是有重复的三元组。

3.也要考虑left和right的去重。我们应该先把符合条件的三元组先加进结果中,再进行去重。例如(0,0,0),如果先进行去重,那这个三元组就不会被放进结果中了。

完整代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0) return res;//排序后第一个元素大于零,肯定求不出三元组为0
            if(i>0&&nums[i]==nums[i-1]) continue;
            int left=i+1;
            int right=nums.length-1;
            while(left<right){
                int sum=nums[i]+nums[left]+nums[right];
                if(sum<0){
                    left++;
                }else if(sum>0){
                    right--;
                }else{
                    res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while(right>left&&nums[right]==nums[right-1]) right--;
                    while(right>left&&nums[left]==nums[left+1]) left++;
                    right--;
                    left++;
                }
            }
        }
        return res;
    }
}

力扣18.四数之和

题目链接:https://leetcode.cn/problems/4sum/

思路

和三数之和思路一致,只是再套一层for循环,同时也要注意对j的去重。

完整代码

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0&&nums[i]>target) return res;
            if(i>0&&nums[i]==nums[i-1]) continue;
            for(int j=i+1;j<nums.length;j++){
                if(j>i+1&&nums[j]==nums[j-1]) continue;
                int left=j+1;
                int right=nums.length-1;
                while(left<right){
                    int sum=nums[i]+nums[j]+nums[left]+nums[right];
                    if(sum>target){
                        right--;
                    }else if(sum<target){
                        left++;
                    }else{
                        res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(left<right&&nums[right]==nums[right-1]){right--;}
                        while(left<right&&nums[left]==nums[left+1]){left++;}
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}

总结

贴一下卡哥的哈希表总结,刷到哈希表时常看看,哪种情况用哪种数据结构合适。

https://programmercarl.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值