两数之和、四数相加II、三数之和、四数之和

1. 两数之和

这道题可以暴力也可以用哈希。

首先来说暴力,就是两个嵌套的循环,找到的第一个相加为target的一组数返回。

哈希就相对复杂一点。当然大家可能会有疑问,什么时候使用哈希,使用哪种哈希?每当我们遇到要判断这种元素是否出现过时,就可以使用哈希,具体使用哪种可以看我之前的文章。对于本题,我们要找到和为目标值的数的下标,首先找到这两个数,再找到下标,相当于key和value,且key不能重复,所以要使用HashMap。代码如下

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
     Map<Integer,Integer> map=new HashMap<>();
     for(int i=0;i<nums.length;i++){
        int s=target-nums[i];
        if(map.containsKey(s)){
            return new int[]{map.get(s),i};
        }
        map.put(nums[i],i);
     }
     return new int[0];
    }
}

令s=target-nums[i],查询map中是否有nums[i]的另一半,如果有就返回,如果没有就存到map中继续向后循环。

454. 四数相加 II

这道题一个暴力的思路是四个for循环,但这样太麻烦了,我们依然可以使用哈希表。这道题可能出现很大的数,因此不能用数组。又因为我们不仅要统计这个数是否出现过,还要统计出现的次数,因此还是用HashMap。代码如下

java 复制代码
class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        Map<Integer,Integer> map=new HashMap<>();
        int count=0;
        for(int a:A){
            for(int b:B){
                map.put(a+b,map.getOrDefault(a+b,0)+1);  
            }
        }
        for(int c:C){
            for(int d:D){
                if(map.containsKey(-c-d)){
                    count+=map.get(-c-d);
                }
            }
        }
        return count;
    }
}

我们先将a、b两个数组的数相加,存到map中,如果有重复的就让value的值加一。之后让c、d两个数组的值相加,判断map中是否有-(c+d)的值,如果有就让次数加上value。

我们要找的是a+b+c+d=0,所以a+b=-(c+d),因此找-(c+d),又因为不需要去重,所以次数加的是value的。

15. 三数之和

这道题也可以用哈希来做,但比较复杂,我们可以使用双指针的方法。我们需要在一个数组里找出三个数相加等于0,且不能重复。

我们可以建立一个for循环,之后创建两个指针,不过前提是将他们升序排列。如果nums[i]>0,则直接退出循环。之后就看nums[i]+nums[left]+nums[right]的值,如果大于0,就让right--,如果小于0,就让left++。又因为不能重复,所以nums[i]如果和nums[i-1]相等的话,则要跳过这一次循环,left和right也是一样。代码如下

java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans=new ArrayList<List<Integer>>();
        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;
            while(right>left){
                if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else if(nums[i]+nums[left]+nums[right]<0){
                    left++;
                }else{
                    List<Integer> list=new ArrayList<Integer>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    while(right>left&&nums[right]==nums[right-1]){
                    right--;
                }
                while(left<right&&nums[left]==nums[left+1]){
                    left++;
                }
                left++;
                right--;
                }
                
            }
        }
        return ans;
    }
}

18. 四数之和

这题跟三数之和很相似,只不过多了一个数,那我们就用两个循环。

代码如下。

java 复制代码
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
          Arrays.sort(nums);
        List<List<Integer>> ans=new ArrayList<List<Integer>>();
        for(int i=0;i<nums.length;i++){
            for(int k=i+1;k<nums.length;k++){
            if((nums[i]>target&&target>0)||(nums[i]+nums[k]>target&&target>0))
            break;
            if((i>0&&nums[i]==nums[i-1])||(k>i+1&&nums[k]==nums[k-1]))
            continue;
            int left=k+1;
            int right=nums.length-1;
            while(right>left){
                if((long)nums[i]+nums[left]+nums[right]+nums[k]>target){
                    right--;
                }else if((long)nums[i]+nums[left]+nums[right]+nums[k]<target){
                    left++;
                }else{
                    List<Integer> list=new ArrayList<Integer>();
                    list.add(nums[i]);
                    list.add(nums[k]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    while(right>left&&nums[right]==nums[right-1]){
                    right--;
                }
                while(left<right&&nums[left]==nums[left+1]){
                    left++;
                }
                left++;
                right--;
                }
                
            }
        }
        }
        return ans;
    }
}
相关推荐
人道领域1 小时前
javaWeb从入门到进阶(SpringBoot基础案例3)
java·spring boot·后端
机器学习之心1 小时前
基于AHP(层次分析法)-模糊综合评价法的工程实践能力评价系统MATLAB代码
算法·matlab·层次分析法·模糊综合评价法
西门吹-禅2 小时前
.gradle迁移d盘
java
士别三日&&当刮目相看2 小时前
Spring两大核心思想:IoC和AOP
java·spring
好学且牛逼的马2 小时前
【Hot100|19-LeetCode 48. 旋转图像 】
leetcode
轩情吖2 小时前
数据结构-并查集
开发语言·数据结构·c++·后端··并查集
你想考研啊2 小时前
win11配置maven
java·数据库·maven
好奇龙猫2 小时前
大学院-筆記試験練習:线性代数和数据结构(20)
数据结构·线性代数
好学且牛逼的马2 小时前
【Hot100|18-LeetCode 54. 螺旋矩阵】
算法·leetcode·矩阵