LeetCode 18. 四数之和 Java题解

这道题是扩展的三数之和。在三数之和中,我们固定a,利用双指针寻找b和c(两头分别开始找),将复杂度从3次方降到了2次方。在四数之和中,我们固定a和b,双指针寻找c和d。将复杂度从4次方降到了3次方。

1.考虑剪枝情况。如果nums[a]比目标和值大,就一定不可能找到结果吗?如nums[a]是正数,它作为四元组中最小的数都大于结果,那么必定找不到结果了。如果是nums[a]是负数,它大于目标和target(也是一个负数),还可能出现大于nums[a]的负数,比如nums[b]负数,nums[a]+nums[b]会变得更小,是一个更小的负数,还是有可能找到结果的。

2.考虑整数溢出情况,使用long。Java中int类型的最小值是-2147483648,最大值是2147483647。在这个样例中,和可能越界了。

java 复制代码
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        int len=nums.length;
        ArrayList<List<Integer>> res=new ArrayList<>();
        for(int a=0;a<len-3;a++){
            //剪枝:正数最小的数a都大于目标了,肯定没结果。如果是大于目标的负数a,负数a+负数b还是可能小于目标的。
            if(nums[a]>target&&nums[a]>=0){
                break;
            }
            if(a-1>=0&&nums[a-1]==nums[a]){//去重a
                continue;
            }
            for(int b=a+1;b<len-2;b++){
                //剪枝:
                if(nums[a]+nums[b]>target&&nums[a]+nums[b]>=0){
                    break;
                }
                if(b-1>a&&nums[b-1]==nums[b]){//去重b
                    continue;
                }
                long t=target-(long)(nums[a]+nums[b]);//新的寻找目标
                int c=b+1,d=len-1;
                while(c<len&&d>b&&c<d){
                    if(t>(long)nums[len-1]+nums[len-2]){
                        break;
                    }
                    if((long)nums[c]+nums[d]==t){
                        ArrayList<Integer> list=new ArrayList<>();
                        list.add(nums[a]);
                        list.add(nums[b]);
                        list.add(nums[c]);
                        list.add(nums[d]);
                        res.add(list);
                        while(c<d&&nums[c+1]==nums[c]){//去重c
                            c++;
                        }
                        while(c<d&&nums[d-1]==nums[d]){//去重d 
                            d--;
                        }
                        c++;
                        d--;    
                    }
                    else if((long)nums[c]+nums[d]>t){
                        d--;
                    }
                    else{
                        c++;
                    }
                }
            }
        }
        return res;
    }
}
相关推荐
列星随旋27 分钟前
线段树和树状数组的学习
学习·算法
圣保罗的大教堂1 小时前
leetcode 61. 旋转链表 中等
leetcode
500841 小时前
昇腾 CANN 的五层架构,到底分了哪五层
java·人工智能·分布式·架构·ocr·wpf
摇滚侠2 小时前
Java 零基础全套教程,File 类与 IO 流,笔记 177-178
java·开发语言·笔记
全糖可乐气泡水2 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
雨落在了我的手上2 小时前
初始java(十):类和对象(⼆)
java·开发语言
h_a_o777oah3 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师3 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
莫雪歌3 小时前
Java AI 应用开发实践:基于 Spring Boot 实现 Chat、Memory、RAG 与 Tool Calling
java·aigc
SmartBrain4 小时前
AI全栈开发(SDD):慢病管理系统工程级设计
java·大数据·开发语言·人工智能·架构·aigc