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(15)---三数之和(双指针)

leetcode 15. 三数之和

leetcode 15. 三数之和(sort+双指针)

LeetCode 581. 最短无序连续子数组/611. 有效三角形的个数/15. 三数之和/18. 四数之和(双指针)

leetcode(15)三数之和+去重

Leetcode15 三数之和