LeetCode(15 三数之和)

本文深入探讨了解决三数之和问题的高效算法。通过使用双指针技巧优化三重循环,显著提高了查找三个数相加为零的组合的速度。文章详细解释了排序、去重和剪枝等关键步骤,提供了清晰的代码实现。

如题
在这里插入图片描述
最直接的方法一定是禁忌之三重循环了,那么很显然的做法就是双指针优化它了

public static List<List<Integer>> threeSum(int[] nums) {
		List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(nums==null||nums.length<3) {
        	return result;
        }
        Arrays.sort(nums);		//排序
        for(int i=0;i<nums.length-2;i++) {
        	int num =nums[i];	//最小值
        	if(num+nums[i+1]+nums[i+2]>0) {
        		break;  //最小值大于0则后续肯定不存在
        	}
        	if(i>0&&nums[i]==nums[i-1]||nums[i]+nums[nums.length-1]+nums[nums.length-2]<0) {
        		continue;	//相同及最大值判断
        	}
        	int m =i+1;
        	int n =nums.length-1;
        	while(m!=n) {
        		if(num+nums[m]+nums[n]<0||(m>i+1&&nums[m]==nums[m-1])) {  //小于目标值则增大m
        			m++;										//注意判断m处元素若等于前值,则跳过
        		}else {
        			if((num+nums[m]+nums[n]>0||n<nums.length-1&&nums[n]==nums[n+1])) {
        				n--;	//同样的,大于目标值则减小n,对应的需要判断n处元素是否大于后值
        			}else {
        			List<Integer> lis = new ArrayList<Integer>();
    				lis.add(num);
    				lis.add(nums[m]);
    				lis.add(nums[n]);
    				result.add(lis);
    				n--;
        			}       			       			       			
        		}
        	}
        }
        return result;
    }

需要注意去重和剪枝
在这里插入图片描述
写法上可以有小得优化,在符合情况时是可以直接m++同时n–,对应的需要注意退出条件需要变为m<n。暴力的也来一个

public static List<List<Integer>> threeSum1(int[] nums) {
		List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(nums==null||nums.length<3) {
        	return result;
        }
        Arrays.sort(nums);
        for(int i=0;i<nums.length-2;i++) {
        	if(nums[i]>0) {
        		break;
        	}
        	if(i>0&&nums[i]==nums[i-1]) {
        		continue;
        	}
        	for(int m=i+1;m<nums.length-1;m++) {
        		if(m>i+1&&nums[m]==nums[m-1]) {
        			continue;
        		}
        		for(int n=m+1;n<nums.length;n++) {
        			if(n>m+1&&nums[n]==nums[n-1]) {
        				continue;
        			}
        			if(nums[i]+nums[m]+nums[n]==0) {
        				List<Integer> lis = new ArrayList<Integer>();
        				lis.add(nums[i]);
        				lis.add(nums[m]);
        				lis.add(nums[n]);
        				result.add(lis);
        			}
        		}
        	}      	
        }
        return result;
	}

就不测了肯定不好看

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值