面试经典150题——三数之和

​"The road to success and the road to failure are almost exactly the same." - Colin R. Davis

aerial photography of mountain range covered with snow under white and blue sky at daytime

1. 题目描述

2.  题目分析与解析

2.1 思路一——暴力方法

因为三个数相加为0,那么说明其中两个加数的和与另一个加数为相反数则满足题意。所以可以得到暴力方法:两层循环相加两个数,第三层循环判断是否和与当前数是否为相反数。

但是这种算法不用想也会超时,因为复杂度已经到达了O(n^3),所以我们再来想想怎么优化。

2.2 思路二——双指针

对于这种数组的题目,因为它内容是杂乱无序的,我们应该想到将它先进行排序。因为排序后的数组这个有序的信息很可能帮助我们更快地解决题目,所以对于数组问题求解找不到思路的先想想如果它是个有序数组你会怎么做。

对于题目中给出的示例:

如果我们先将它排序,会得到:nums = [-4, -1, -1, 0, 1, 2]:

看到这里有没有一点感觉?如果我们将一个指针指向第一个数,我们只需要考虑它后面的数字中任意两个数字之和为这个指针的相反数就行。而对于有序数组而言,任意两个数字之和是某一个target的值我们之前讲过可以使用双指针分别指向头尾,向目标缩进,而且由于它只需要遍历整个数组一次,因此其时间复杂度为O(N)。再加上一个循环来遍历需要的target,那么就可以得到时间复杂度为O(N^2)的算法。

基本思路为:

  1. 使用指针 i表示需要的target,从头到尾遍历数组

  2. 使用head与end指针,分别指向i+1nums.length - 1的位置

  3. 判断head与end的值的和target的相反数(也就是nums[i]的相反数)的大小

    • 如果大于 - target,则end--

    • 如果小于 - target,则head++

    • 如果相等说明head+end+target刚好为0,满足题意加入结果集,head++,end--

    • 直到 end >= head 退出

但是我们还需要注意题目提到了:

因此我们还需要考虑重复的情况,也就是

  • 对于 i 指向的target与 i + 1指向的target如果相同,我们需要排除掉,因为这回得到相同的三元组结果,因为相同的target的所有可能结果在第一次已经全部获得了。

  • 同时在我们进行判断head与end求和的过程中,如果head++后的值等于head的值就需要跳过,end--后的值等于end的值也需要跳过,因为这相当于同样的加数。

因此根据上述思路就可以写处我们的代码了。

3. 代码实现

3.1 暴力解法

3.2 双指针

4. 运行结果

第一种方法会超时,第二种结果如下:

5. 相关复杂度分析

5.1 暴力解法

时间复杂度:O(N^3)

空间复杂度:O(1)

5.2 双指针

  • 时间复杂度:O(n^2),数组排序O(N log N),遍历数组O(n),双指针O(n),总体复杂度O(N log N) + O(n) * O(n) =O(n^2)

  • 空间复杂度:O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值