[LeetCode] three sums && three cloest sums && four sums

Given an array S of n integers, are there elements abc 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)


思路:假如直接采用三重遍历暴力破解,时间复杂度为O(n^3)。可以参考两个数求和的办法,对于有序数组,找出两个数的和是N的时间复杂度是O(n)。对数组排序,时间复杂度是O(nLog(n))。最后问题变成先选取一个数,然后再剩下的数组中查询target-nums[i]的两个数,注意查重的办法,那么总的时间复杂度O(n^2)+O(nlog(n))=O(n^2)。
public class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        int len=nums.length;
        List<List<Integer>> list=new ArrayList<>();
        for(int i=0;i<len-2;i++)
        {
            //去重
            if(i>0 && nums[i]==nums[i-1]) continue;
            int target2=0-nums[i];
            twoSum(nums, i+1, target2, list);
        }
        return list;
    }
    public void twoSum(int [] nums,int start,int target,List<List<Integer>> list)
    {
        int head=start, end=nums.length-1;
        while(head<end)
        {
            int sum=nums[head]+nums[end];
            if(sum<target)
            {
                head++;
            }
            else if(sum>target)
            {
                end--;
            }
            else 
            {
                List<Integer> temp=new ArrayList<>();
                temp.add(nums[start-1]);
                temp.add(nums[head]);
                temp.add(nums[end]);
                list.add(temp);
                
                //排除可能出现的重复情况,由于是有序数组,从小到大,所以只要一个一个的找重复并跳过即可
                int k=head+1;
                while(k<end && nums[k]==nums[head])k++;
                head=k;
                
                k=end-1;
                while(k>head && nums[k]==nums[end])k--;
                end=k;
            }
        }
    }
}

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

public class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int dis=Integer.MAX_VALUE;
        int result=0;
        for(int i=0;i<nums.length-2;i++)
        {
            int target2=target-nums[i];
            int re=twoSumCloest(nums, i+1, target2);
            int d=Math.abs(target-re-nums[i]);
            if(d<dis)
            {
                dis=d;
                result=re+nums[i];
                if(d==0)
                    return target;
            }
        }
        return result;
    }
    public int twoSumCloest(int [] nums,int start,int target)
    {
        int head=start,tail=nums.length-1;
        int re=0,d=Integer.MAX_VALUE;
        while(head<tail)
        {
            int sum=nums[head]+nums[tail];
            if(sum<target)
            {
                int dis=target-sum;
                if(dis<d)
                {
                    d=dis;
                    re=sum;
                }
                head++;
            }
            else if(target<sum)
            {
                int dis=sum-target;
                if(dis<d)
                {
                    d=dis;
                    re=sum;
                }
                tail--;
            }
            else {
                return target;
            }
        }
        return re;
    }
}
原文地址:https://www.cnblogs.com/maydow/p/4665739.html