【Java】代码随想录哈希表第七天| LeetCode454 四数相加、LeetCode383 赎金信、LeetCode15 三数之和、LeetCode18 四数之和

文章概述了四个LeetCode问题,涉及数组操作,如四数相加(寻找满足特定和的组合)、计数元素出现次数、构造赎金信(检查字符集)和查找三/四数之和(使用排序和双指针策略)。每个问题展示了如何利用数据结构(如哈希表)和算法技巧解决数组相关问题。
摘要由CSDN通过智能技术生成

今日任务 

  •  454.四数相加II 
  •  383. 赎金信 
  •  15. 三数之和 
  •  18. 四数之和 
  •  总结  

LeetCode454 四数相加

题目链接:454. 四数相加

思路:

首先,返回个数,所以建立以a+b总和sum为key,以个数为value的map

最终取符合key=a+b=0-c-d的key值,其value即个数,需要对value进行累加得到总元组个数。

● 用到的函数:

map.get(key)

map.getOrDefault(key)有就加一,没有就创建出初始值为0

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int count = 0;
        Map<Integer,Integer> map1 = new HashMap<>();    //key:元素值之和,value:这个数值出现的次数
        for(int a : nums1){
            for(int b : nums2){
                //map1[a+b]++;  注意java不能这么写
                map1.put(a+b,map1.getOrDefault(a+b,0)+1);
            }
        }
        for(int c: nums3){
            for(int d: nums4){
                int tmp = 0 -c-d;
                if(map1.containsKey(tmp)){
                    count += map1.getOrDefault(tmp,0);
                }
            }
        }
        return count;
    }
}

LeetCode383 赎金信

题目链接:383.赎金信

思路:是否存在?用数组

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

LeetCode15 三数之和

题目链接:15. 三数之和

思路:1. 两数之和    这道题需要求出两个数(key)对应的下标(value),不要求去重

而这道题明确要求给出不重复的三元组

因此应首先用双指针法,即首先进行排序,

在一个i的for循环中,通过left和right指针来找到合适的三元组

但是为了使三元组不重复,i不能重复,left和right也不能重复(对abc都要做出剪枝的操作)

● Arrays.sort();  对数组从小到大进行排序      Arrays.asList(a,b,c);       将数组转化成list[a,b,c]

● 动态三元组[ [a,b,c ], [ a,b,c] ]:List <List<Integer>> res = new ArrayList<>();

●区别 arraylist数组,集合set,和映射map用的不同函数

代码:

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){
                break;
            }
            if(i>0 && nums[i] == nums[i-1]){
                continue;
            }
            int left = i+1;
            int right = nums.length - 1;
            int sum = nums[i] + nums[left] + nums[right];
            while(left<right){
                if(sum<0)    left++;
                else if(sum>0)   right--;
                else{
                    res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    //必须加入right>left的判断条件以免移动的过头
                    while(right > left && nums[left]==nums[left+1]) left++;
                    while(right > left && nums[right]==nums[right-1])   right--;
                    // 双指针本身还是要移动的
                    left++;
                    right--;
                }
            }
        }
        return res;
    }
}

LeetCode18 四数之和

题目链接:18.四数之和

思路:比三数之和多了一重for循环和去重的操作

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]>target){ //剪枝
                break;
            }
            if(i > 0 && nums[i] == nums[i-1]){  //对nums[i]去重
                continue;
            }
            for(int j=i+1;j<nums.length;j++){
                if(j > i+1 && nums[j] == nums[j-1]){  //对nums[j]去重(允许j=i+1的首次情况发生)
                    continue;
                }
                int left = j+1;
                int right = nums.length-1;
                //因为left、right都在变,所以不能放在外面
                //int sum = nums[i]+nums[j]+nums[left]+nums[right];
                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[left]==nums[left+1])left++;
                        while(left<right && nums[right]==nums[right-1])right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值