LeetCode 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

 

class Solution3 {
	public List<List<Integer>> threeSum(int[] nums) {
		List<Integer> a = new ArrayList<Integer>();
		List<List<Integer>> b = new ArrayList<List<Integer>>();
		Arrays.sort(nums);
	  
			 for(int i=0;i<nums.length;i++) {
				 int target = 0-nums[i];
				 if(i>1 && nums[i]==nums[i-1]) 
					 continue;
				 int  k =i+1;
				 int l=nums.length-1;
				 while(k<l) {
					 int xx=nums[k]+ nums[l];
					 if( xx  == target) {
						 a.add(nums[i]);
						 a.add(nums[k]);
						 a.add(nums[l]);
						 b.add(new ArrayList<Integer>(a)); // 此处如果b.add(a) 则 a clear后,b中的a也没了
						 a.clear();
						 k=k+1;
					 } else if(xx  < target) {
						 k=k+1;
					} else if( xx >target) {
						 l=l-1;
					 }
					 
				 }
				 
			 }
		 
						 
	 // 通过hashset 去除重复
		HashSet h = new HashSet(b);
		b.clear();
		b.addAll(h);
		return b;
	}
}

基本思想  

      先把 nums数组从小到大排序,最左端最小,最右端最大 。

      从左 到右 从固定 一个数,然后把target 定位其 相反数, 然后 再找 两个数的和等于 target 即可。

 【a0,a1,a2,a3,a4,a5,a6,a7】

    先 令 target =a0;

   然后 int k ,l 分别指向 a1,a7 

   第一次 while(k<l)

        如果 a1+a7==target ,就加到 b 中 ,然后 k+1 指向  a2

       如果 a1+a7<target  ,那么 最大的a7 都不能 满足,说明没有能 数 与a1之和能等于target, 则 直接  k+1  ,指向a2

        如果 a1+a7>target  , 则  l-1,指向 a6 ,继续 while(k<l) 循环    

    第二次while(k>l)

        如果 a1+a6==target .............

        如果 a1+a6<target ,因为  a1+a7>target ,而a1+ a6<target ,说明没有能 数 与a1之和能等于target, 则 直接  k+1  ,指向a2

      如果 a1+a6>target .............

再令 target = a1;

   l 指向 a7 ,但是

   注意  此时 不用 再次 把 k 指向 a0、a2、a3、a4..... ,直接 从 指向 a2 即可,因为 如果指向 a0 ,即 通过 l 向左遍历 寻找一个数,使得 a0+a(?) ==  -  a1  也就是  a1+a(?) == -a0 ,与第一次 令target=a0 重复,所以直接 把 k指向当前target 的下一个数 ,即代码的第11行

    

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值