三位数之和

三位数之和

难点在于跳过重复,多举例子就好了,当然也可以使用set去重复但是效率较低。

直接暴力会超时,时间复杂度为O(n2lgn).

解法一:两层循环,第三个使用二分查找。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<List<Integer>>();
        for(int i=0;i<nums.length-2;i++){
            if(i>0 && nums[i-1]==nums[i])
                continue;
            for(int j=nums.length-1;j>i+1;j--){
                if(j<nums.length-1 && nums[j+1]==nums[j])
                    continue;
                int first=i+1,end=j-1;
                int mid=(i+j)/2;
                int temp=-(nums[i]+nums[j]);
                while(first<=end){
                    if(nums[mid]>temp)
                        end=mid-1;
                    else if(nums[mid]<temp)
                        first=mid+1;
                    else{
                        List<Integer> tempres=new ArrayList<Integer>();
                        tempres.add(nums[i]);
                        tempres.add(nums[mid]);
                        tempres.add(nums[j]);
                        res.add(new ArrayList(tempres));
                        break;
                    }
                    mid=(first+end)/2;
                }
            }
        }
        return res;
    }
}

解法二: 一层循环,然后转换成求两个数和的问题。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<List<Integer>>();
        for(int i=0;i<nums.length-2;i++){
            if(i>0 && nums[i-1]==nums[i])
                continue;
            int temp=-nums[i];
            Map<Integer,Integer> map=new HashMap<Integer, Integer>();
            int tempnum=-1;
            for(int j=i+1;j<nums.length;j++){
                int temp2=temp-nums[j];
                if(map.containsKey(temp2) && nums[j]!=tempnum){
                    List<Integer> tempres=new ArrayList<Integer>();
                    tempres.add(nums[i]);
                    tempres.add(temp2);
                    tempres.add(nums[j]);
                    res.add(new ArrayList(tempres));
                    tempnum=nums[j];
                }
                map.put(nums[j],j);
            }
        }
        return res;
    }
}

解法三:一层循环,双指针。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<List<Integer>>();
        for(int i=0;i<nums.length-2;i++){
            if(i>0 && nums[i-1]==nums[i])
                continue;
            int first=i+1,end=nums.length-1;
            int temp=-nums[i];
            while(first<end){
                while(nums[first]+nums[end]<temp && first<end)
                    first++;
                while(nums[first]+nums[end]>temp && first<end)
                    end--;
                if(first<end && nums[first]+nums[end]==temp){
                    List<Integer> tempres=new ArrayList<Integer>();
                    tempres.add(nums[i]);
                    tempres.add(nums[first]);
                    tempres.add(nums[end]);
                    res.add(new ArrayList(tempres));
                    while(first<end) {
                        if(nums[first+1]==nums[first])
                            first++;
                        else
                            break;
                    }
                    first++;
                    while(first<=end){
                        if(nums[end-1]==nums[end])
                            end--;
                        else
                            break;
                    }
                    end--;
                }
            }
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/anhuibozhoushatu/article/details/84259260