LeetCode 15.三数之和

Posted 阿乐246

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 15.三数之和相关的知识,希望对你有一定的参考价值。

一、题目详情

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

二、思路

首先能想到的就是嵌套三层循环,找到所有满足条件的组合,然后再进行复杂繁琐的去重操作,太过麻烦,时间复杂度O(N³)。
而先进行去重操作,然后使用普通的三层循环,这样比较简单。为了保证答案不重复,直接将数组中的元素进行从小到大的排序。
同时,对于每一重循环,相邻两次枚举的元素不能相同,否则也会造成重复。

三、算法

伪代码实现:

nums.sort()
for first = 0 .. n-1
    // 只有和上一次枚举的元素不相同,我们才会进行枚举
    if first == 0 or nums[first] != nums[first-1] then
        for second = first+1 .. n-1
            if second == first+1 or nums[second] != nums[second-1] then
                for third = second+1 .. n-1
                    if third == second+1 or nums[third] != nums[third-1] then
                        // 判断是否有 a+b+c==0
                        check(first, second, third)

优化:
如果有三元组(a,b,c),满足a+b+c=0,当第二重循环向右枚举下一个元素b’时,因为b’>b,那么满足a+b’+c’=0的c’一定有c’<c。
所以可以使用双指针的方法,第二重循环不变继续从左向右,第三重循环从右向左。
总的时间复杂度,也变成了O(N²)。

nums.sort()
for first = 0 .. n-1
    if first == 0 or nums[first] != nums[first-1] then
        // 第三重循环对应的指针
        third = n-1
        for second = first+1 .. n-1
            if second == first+1 or nums[second] != nums[second-1] then
                // 向左移动指针,直到 a+b+c 不大于 0
                while nums[first]+nums[second]+nums[third] > 0
                    third = third-1
                // 判断是否有 a+b+c==0
                check(first, second, third)

四、代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int length=nums.length;
		Arrays.sort(nums);
		List<List<Integer>> ans=new ArrayList<List<Integer>>();
		for(int i=0;i<length;i++) {
			if(i!=0 && nums[i]==nums[i-1])
				continue;
			int k=length-1; //在第二重循环外初始化k
			for(int j=i+1;j<length;j++) {
				if(j!=i+1 && nums[j]==nums[j-1])
					continue;
				while(nums[i]+nums[j]+nums[k]>0 && j<k) {
					k--;
				}
				//指针重合之后,b继续增加,不可能再有满足条件的c了
				if(j==k)
					break;
				if(nums[i]+nums[j]+nums[k]==0) {
					List<Integer> temp=new ArrayList<Integer>();
					temp.add(nums[i]);
					temp.add(nums[j]);
					temp.add(nums[k]);
					ans.add(temp);
				}
			}
		}
		return ans;
    }
}





code

以上是关于LeetCode 15.三数之和的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode15.三数之和(C++,Python)

LeetCode15.三数之和(C++,Python)

leetcode(15)三数之和+去重

LeetCode1两数之和15三数之和

LeetCode1两数之和15三数之和

LeetCode刷题15-简单-三数之和