leetcode15. 3Sum

15. 3Sum

1、原题

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.

2、解读与思路

这道题目的意思不是很难理解,就是要求我们找到一个数组中所有3个数之后为0的不同组合。
思路:一开始看到这道题并没有什么好的想法;就只好采用最笨的方法了,则就是遍历三遍数组。当然简单的遍历三遍肯定是要超时的。所以我们要对其进行相应的优化。
1、首先对数组进行快排,获得一个从小到大的有序数组。
2、开始遍历数组,优化将三层变为两层,第一层数组i从0到length-1;第二层j,k两个小标,j从i+1开始,k则从length-1开始;当j与k相遇时则结束第二层的遍历或三个数相加为0时也结束当前第二层遍历.
3、细节注意,由于是要找到不同的组合,所有我们在遍历时要进行相应的判断才行。

3、实现代码

public class Solution {
    //快排
    public void quickSort(int[] nums, int low, int high) {
		int l = low;
		int h = high;
		int item = nums[l];
		
		while (l < h) {
			while (l < h && nums[h] >= item) {
				h--;
			}
			if (l < h) {
				int temp = nums[l];
				nums[l] = nums[h];
				nums[h] = temp;
			}
			
			while (l < h && nums[l] <= item) {
				l++;
			}
			if (l < h) {
				int temp = nums[l];
				nums[l] = nums[h];
				nums[h] = temp;
			}
		}
		
		if (l > low) {
			quickSort(nums, low, l - 1);
		}
		if (h < high) {
			quickSort(nums, l + 1, high);
		}
	}
	
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> finals = new ArrayList<List<Integer>>();
		if (nums.length == 0) {
			return finals;
		}
		//排序
		quickSort(nums, 0, nums.length - 1);
		
		for (int i = 0; i < nums.length; i++) {
		    //由于从小到大排序,nums[i]大于0时肯定结束了
			if (nums[i] > 0) {
				break;
			}
			//排除nums[i]相同的情况
			if (i > 0 && nums[i] == nums[i-1]) {
			    continue;
			}
			//定义第二层两个下标
    		int j = i + 1;
    		int k = nums.length - 1;  
            int target = -nums[i];
            while (j < k) {
                if (nums[j] + nums[k] == target) {
                    finals.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    j++;
                    k--;
                    //排除nums[j]与nums[i]相同的情况
                    while (j < k && nums[j] == nums[j - 1]) {
                        j++;
                    }
                    while (j < k && nums[k] == nums[k + 1]) {
                        k--;
                    }
                } else if (nums[j] + nums[k] > target) {
                    //大于0说明nums[k]过大,将其减小
                    k--;
                } else {
                    //小于0说明目前nums[j]过小,将其增大
                    j++;
                }
            }
		}
		return finals;
    }
}

4、总结与思考

在看提交记录时,发现有两个不同的集中区域;不幸的是我在靠后的集中区域;这就表明还有一种较优的方法我还没有想到。待我静静思考再来看一看。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值