LeetCode.15.3Sum —— 解题

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.


Note:


Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets.
    For example, given array S = {-1 0 1 2 -1 -4},
    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
问题:求数组中,所有和为0 的三个元素。

解题思路:
直接用三重循环扔上去超时了,然后在网上看到使用双指针的算法,理解后,把这道题解决了。

第一步,对数组排序。

第二步,

对于元素 S[i] , 最后的答案可以分为两种,包含 S[i] 的,和不包含 S[i] 的。当包含 S[i] 的情况都找到后,后续就可以不用在考虑 S[i] 。
对于 S[i] , l = i+1, r = len-1 。若 s[i] + S[l] + S[r] == 0, 则为原问题的一个解。

当 S[i] + S[l] > -S[r] 时,则 r--
当 S[i] + S[l] < -S[r] 时,则 l++
当 S[i] + S[i] = -S[r] 时, 表示是原问题的一个解,则 l++, r--;(这里使用的一层循环,我使用的两层,可以通过测试)


第三步,性能优化。同样根据分析1,若 S[i] == S[i+1],可以跳过。


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        
        //先排序,则可以简单判断第一个元素重复,以及避免三个元素一样只是顺序不同
    	Arrays.sort(nums);
  	
        List<Integer> subList = new ArrayList<Integer>();
        for(int i=0; i<nums.length-2; i++){
        <span style="white-space:pre">	</span>//判断nums[i]是否等于num[i-1],相等则已经查找过了,就进行下一次循环
            if(i>0&&nums[i]==nums[i-1]) continue;
            //现在nums[i]已经大于0,后面也不会有结果
            if(nums[i]>0) break;

            for(int j=i+1; j<nums.length-1; j++){
            	//nums[j-1]等于nums[j],并且不等于nums[i],说明已经查找过了,下一次循环
            	//这样两次判断,加上nums从小到大排序了,所以确定了三个元素中前两个不会重复,即查找的结果都是唯一的
            	if(nums[j]==nums[j-1]&&j!=i+1) continue;
            	//每次j循环,k从最大递减,直到三个数相加小于等于0,再判断是否为0,之后的数不用比较了
            	int k=nums.length-1;
                while(nums[i]+nums[j]+nums[k] > 0 && k>j+1){
                	k--;
                }
                if(nums[i]+nums[j]+nums[k] == 0){
                    subList.clear();
                    subList.add(nums[i]);
                    subList.add(nums[j]);
                    subList.add(nums[k]);
                    //注意新建list存入,不然最后全部是一样的
                    result.add(new ArrayList<Integer>(subList));
                }
                
            }
        }
        return result;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值