Leetcode15. 三数之和(双指针)
Posted !0 !
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode15. 三数之和(双指针)相关的知识,希望对你有一定的参考价值。
题目链接:https://leetcode-cn.com/problems/3sum/
解题思路
如果暴力枚举答案我们需要O(n^3)的时间复杂度,有没有什么办法可以优化呢?一般我们对于数组的题都可以用到双指针,而双指针算法一般都是有规律的,所以我们可以先排序,然后用指针i从左往右枚举数组中的元素,利用双指针l,r遍历i右边的元素找出使得三者之和等于0的答案。
思路很简单,但是有很多小优化,具体看代码。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<>();
for(int i = 0; i < nums.length - 2; i++) {
if(nums[i] > 0) //如果nums[i]>0则说明之后的元素肯定都等于0,三者之和不可能等于0
break;
int l = i + 1, r = nums.length - 1; //l从i后一个位置开始,r从最后一个元素开始
while(l < r) {
if(nums[l] + nums[r] + nums[i] > 0) r--; //总体大于0,则使r减小,总体之和也会减小
else if(nums[l] + nums[r] + nums[i] < 0) l++; //总体小于0,则使l增大,总体之和也会增大
else { //找到了答案
ans.add(Arrays.asList(nums[i], nums[l],nums[r])); //将答案放入答案集合中
while(l < r && nums[l] == nums[l + 1]) //去重,因为答案中不能包含重复的三元组
l++;
while(l < r && nums[r] == nums[r - 1]) //去重
r--;
l++;
r--;
}
}
while(i < nums.length - 1 && nums[i] == nums[i + 1]) //去重
i++;
}
return ans;
}
}
复杂度分析
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
以上是关于Leetcode15. 三数之和(双指针)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 581. 最短无序连续子数组/611. 有效三角形的个数/15. 三数之和/18. 四数之和(双指针)