3Sum -- LeetCode

本文深入解析了LeetCode上的经典算法题3Sum,介绍了如何通过排序和夹逼技巧将时间复杂度从O(n^3)降低到O(n^2),并通过代码示例详细解释了避免重复结果的处理方法。
               

原题链接: https://oj.leetcode.com/problems/3sum/

这道题是Two Sum的扩展,brute force时间复杂度为O(n^3), 对每三个数进行比较。这道题和Two Sum有所不同,使用哈希表的解法并不是很方便,因为结果数组中元素可能重复,如果不排序对于重复的处理将会比较麻烦,因此这道题一般使用排序之后夹逼的方法,总的时间复杂度为O(n^2+nlogn)=(n^2),空间复杂度是O(n),代码如下:

public ArrayList<ArrayList<Integer>> threeSum(int[] num){    ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();    if(num==null || num.length<=2)        return res;    Arrays.sort(num);    for(int i=num.length-1;i>=2;i--)    {        if(i<num.length-1 && num[i]==num[i+1])            continue;         ArrayList<ArrayList<Integer>> curRes = twoSum(num,i-1,-num[i]);         for(int j=0;j<curRes.size();j++)         {             curRes.get(j).add(num[i]);         }         res.addAll(curRes);    }    return res;}private ArrayList<ArrayList<Integer>> twoSum(int[] num, int end,int target){    ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();    if(num==null || num.length<=1)        return res;    int l = 0;    int r = end;    while(l<r)    {        if(num[l]+num[r]==target)        {            ArrayList<Integer> item = new ArrayList<Integer>();            item.add(num[l]);            item.add(num[r]);            res.add(item);            l++;            r--;            while(l<r&&num[l]==num[l-1])                l++;            while(l<r&&num[r]==num[r+1])                r--;        }        else if(num[l]+num[r]>target)        {            r--;        }        else        {            l++;        }    }    return res;}
注意,在这里为了避免重复结果,对于已经判断过的数会skip掉,这也是排序带来的方便。 这道题考察的点其实和 Two Sum 差不多, Two Sum 是3Sum的一个subroutine, 不过更加综合一些,实现上更加全面,需要注意细节,面试中比较常见的一道题。此题更加复杂的扩展是4Sum,请参见4Sum -- LeetCode


           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值