leetcode18.四数之和——学习笔记

题目:力扣icon-default.png?t=L9C2https://leetcode-cn.com/problems/4sum/

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);
        int l;
        int r;
        for(int index1=0;index1<nums.length-3;index1++){
            if(index1!=0&&nums[index1]==nums[index1-1]){
                continue;
            }
            for(int index2=index1+1;index2<nums.length-2;index2++){
                if(index2!=index1+1&&nums[index2]==nums[index2-1]){
                    continue;
                }
                l = index2+1;
                r = nums.length-1;
                while(l<r){
                    if(nums[index1]+nums[index2]+nums[l]+nums[r]==target){
                        List<Integer> list = new ArrayList<>();
                        list.add(nums[index1]);
                        list.add(nums[index2]);
                        list.add(nums[l]);
                        list.add(nums[r]);
                        ans.add(list);
                        while(l<r&&nums[l]==nums[l+1]) l++;
                        while(l<r&&nums[r]==nums[r-1]) r--;
                        l++;
                        r--;
                    }else{
                        if(nums[index1]+nums[index2]+nums[l]+nums[r]>target){
                            r--;
                        }else{
                            l++;
                        }
                    }
                }
            }
        }
        return ans;
    }
}

 

思路:这题和leetcode15.三数之和非常相似,这里的思路和三数之和那题的思路也是大同小异。三数之和的思路是先排序,枚举第一个数,然后用双指针法找符合题目要求的两个元素;而这里也是先排序,接着分别枚举前两个元素,然后再用双指针法如法炮制的寻找符合题目要求的两个元素。

1.声明List类型的变量ans,这个就是需要返回的元素;通过Array.sotr()的方法对nums[]数组进行排序操作;分别声明l和r,它们两分别为左指针和右指针。

List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
int l;
int r;

 2.index1是枚举的第一个元素,index2是枚举的第二个元素。为了避免枚举同样的元素导致重复解,因此需要判断当索引所指的元素的值是否与上一个索引所指的元素的值一致,若一致则需要跳开。index也需要进行上述判断重复的操作。然后分别对左指针l与右指针r赋值,左指针初始值应为枚举的第二个元素的下一个元素,而右指针的初始值应为该数组的最后一个元素。

for(int index1=0;index1<nums.length-3;index1++){
    if(index1!=0&&nums[index1]==nums[index1-1]){
        continue;
    }
    for(int index2=index1+1;index2<nums.length-2;index2++){
        if(index2!=index1+1&&nums[index2]==nums[index2-1]){
            continue;
        }
    l = index2+1;
    r = nums.length-1;
    //......
    }
}

3.若四数之和的值等于target则将这四个元素的值存入list中,然后再将list存入ans中,然后同时将左指针右移和右指针左移(若指针指向的元素的值与上一个指向元素的值相同,则再移动该指针,避免指向重复值导致重复解)。若四数之和的值不等于target,则需要判断四数之和大于还是小于target。若四数之和大于target,则将右指针左移;若四数之和小于target,则将左指针右移。直至移动到左右指针重合,则结束。

while(l<r){
    if(nums[index1]+nums[index2]+nums[l]+nums[r]==target){
        List<Integer> list = new ArrayList<>();
        list.add(nums[index1]);
        list.add(nums[index2]);
        list.add(nums[l]);
        list.add(nums[r]);
        ans.add(list);
        while(l<r&&nums[l]==nums[l+1]) l++;
        while(l<r&&nums[r]==nums[r-1]) r--;
        l++;
        r--;
    }else{
        if(nums[index1]+nums[index2]+nums[l]+nums[r]>target){
            r--;
        }else{
            l++;
        }
    }
}

4.完成上述循环之后,ans已经存好题目所需的答案,返回即可。

return ans;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值