代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和、总结

文章讲述了在解决四数相加II、赎金信、三数之和及四数之和的编程问题中,如何运用哈希表和双指针技术。对于四数相加II,利用哈希表存储两数组之和的频率;赎金信问题通过计数字符出现次数判断能否构造;三数之和与四数之和则涉及排序和双指针去重的技巧。
摘要由CSDN通过智能技术生成

代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和、总结

454.四数相加II

题目

454.四数相加II

代码与思考过程

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer, Integer> map = new HashMap<>();//设置一个hashmap
        int sum;
        int result=0;
        for(int i=0;i<nums1.length;i++){//求出nums1+2的总和
            int num1 =nums1[i];
            for(int j=0;j<nums2.length;j++){
                int num2=nums2[j];
                sum=num1+num2;
                if(map.containsKey(sum)){//如果出现重复的sum
                    map.put(sum,map.get(sum)+1);//将value进行+1操作
                }else{
                    map.put(sum,1);//无,这加入map
                }
            }
        }
        for(int i=0;i<nums3.length;i++){//求出nums3+4的总和
            int num3=nums3[i];
            for(int j=0;j<nums4.length;j++){
                int num4=nums4[j];
                sum=num3+num4;
                if(map.containsKey(0-sum)){//如果出现重复的0-sum
                    result+=map.get(0-sum);//让结果等于map的value
                }
            }
        }
        return result;
    }
}

对于这题我有意识到用双加然后做减法,但是我一开始没有用map(想试一下数组可不可以,顺便试一下自己)而且我但是也不知道map之中key和value分别存放什么东西,所以就没有用map后面自己想不到,就看过程了,因为已经2刷一遍所以就很容易看懂了

383. 赎金信

题目

383. 赎金信

代码与思考过程

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[]find=new int[26];//设立26字母
        for(int i=0;i<magazine.length();i++){
            find[magazine.charAt(i)-'a']++;//让ma每个元素都与a的ASCII进行相减
        }
        for(int i=0;i<ransomNote.length();i++){
            find[ransomNote.charAt(i)-'a']--;//让ran每个元素都与a的ASCII进行相减
        }
        for(int i=0;i<find.length;i++){
            if(find[i]<0){//小于0意味着有不相同的元素
                return false;
            }
        }
        return true;
    }
}

有一说一,我看到的时候就已经知道要用数组来进行了,跟242.有效的字母异位词 思路是一致,就是找到26个小写字母的ascii码。

15. 三数之和

题目

15. 三数之和

代码与思考过程

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();//!!!!!!
        int left;
        int right;
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0){
                return result;
            }
            if(i>0&&nums[i]==nums[i-1]){//进行i的去重处理
                continue;
            }
            left=i+1;
            right=nums.length-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else if(nums[i]+nums[left]+nums[right]<0){
                    left++;
                }else{
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));//!!!!!
                    while(right>left&&nums[right]==nums[right-1]){//进行right的去重处理
                        right--;
                    }
                    while(right>left&&nums[left]==nums[left+1]){//进行left的去重处理
                        left++;
                    }
                    right--;
                    left++;

                }
            }
        }
        return result;
    }
}

对于这个题目我一开始想用跟四数相加II一样的方法但是,我看了输出的result,好像返回不是一个东西,要进行去重,然后死在去重,因为没有排序,想用for循环,想了一下会超时,就选择观看答案了。
去重处理就是i那里要注意i-1,因为i+1是left,遇到[-1,-1,2]就不行!

18. 四数之和

题目

18. 四数之和

代码与思考过程

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

因为返回的值和三数之和是一样的所以过程基本一致就是多一层for,注意一下j和j-1就可以了!

总结

对于类似454那种题目输出的是出现次数,可以不用去重操作的时候就可以使用一下map来进行寻找元素。而383. 赎金信就是242.有效的字母异位词 就是变了一下代码一些顺序就没有了,甚至基本一致!
15. 三数之和、18. 四数之和是一种类型的题目,题目要求的是求他的元组,然后要进行去重(元组不能有重复元素)用hash去重就很麻烦。(其实我感觉可以用map,当value多于1时候continue )用双指针就相对于简单,所以要与之前的知识相结合来做!List<List> result = new ArrayList<>();(多元组的创建是这样的)Map<Integer, Integer> map = new HashMap<>();//设置一个hashmap

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值