LeetCode-3Sum

算法分析与设计第6周博客

15. 3Sum

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
题目的意思很简单,就是给出一组整数,找出其中所有三个和为零的数的集合。

如果使用暴力枚举法的话,那么就是从n个数中取出3个,计算它们的和,看其是否为零,这样的时间复杂度是O(n^3),算是很低的效率了。

如果先进行排序呢,排序的时间复杂度是O(n*log(n)),这样就得到了一个有序的数组,如果我们首先确定一个数A[i],然后去剩下的A[i+1]-A[n-1]中寻找两个数,这两个数的和是-A[i]。这样,就把这个问题由三个数的和变成了两个数的和。如果读者熟悉的话,在一个有序的数组里,寻找两个数的和是否等于某个数,这个算法的时间复杂度是O(n),具体的代码如下:

boolean twoSum(int[] nums, int target) {
		for (int i = 0, j = nums.length-1; i < j; ) {
			if (nums[i]+nums[j] > target)
				--j;
			else if (nums[i]+nums[j] < target)
				++i;
			else
				return true;
		}
		return false;
	}
这样,就基本解决这个问题了。还有一个需要注意的细节是,返回的集合中是不能有相同的元素的,所以遇到相同的元素的时候,需要跳过。整体的代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Solution {
	public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        int i = 0, j = nums.length-1;
        for (i = 0; i < nums.length; ++i) {
            if (i > 0 && nums[i] == nums[i-1])
                continue;
			int s = i+1, e = nums.length-1;
			while (s < e) {
				if (nums[s]+nums[e]+nums[i] > 0) {
					--e;
				} else if (nums[s]+nums[e]+nums[i] < 0) {
					++s;
				} else {
					List<Integer> one = new ArrayList<>();
	        		one.add(nums[i]);
	        		one.add(nums[s]);
	        		one.add(nums[e]);
	        		res.add(one);
                    
                    do {
                        ++s;
                    } while (s < nums.length && nums[s] == nums[s-1]);
                    do {
                        --e;
                    } while (e > 0 && nums[e] == nums[e+1]);
				}
			}
		}
        return res;
    }
	
}


这个算法的时间复杂度右两部分组成,排序(O(n*log(n)),需找三个数的和O(n*n),所以最终的时间复杂度也是O(n^2)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值