题目难度:Medium

题目:

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.

翻译:

给定一个n个整数的数组S,S中是否存在有a b c三个元素使得a+b+c=0?在S中找到所有的非重复组合,使它们的和为0

注意:答案集不能包含重复的数组。例如:[1,5,-6]与[-6,5,1]等数组,答案只出现其中一个

思路:三。。。个。。for循环??

(⊙x⊙;)。。。就要写!

Code:311 / 313 test cases passed.   ——  Time Limit Exceeded      时间复杂度:O(N3)

     public static List<List<Integer>> threeSum1(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> outList = new ArrayList<List<Integer>>();
for (int i = 0; i < nums.length; i++) {
if ((i > 0 && nums[i] == nums[i - 1])) // 各循环起始点不需要判断重复
continue; // 不用i++ 的原因:避免最后的k还要增加边界判断,进入下一个循环则会自动边界判断“i < nums.length”
for (int j = i + 1; j < nums.length; j++) {
if ((j > i + 1 && nums[j] == nums[j - 1]))
continue; // 当有很多for和if的时候,条件取反后用continue,以此取代if的{}缩进,使代码可读性增加
for (int k = j + 1; k < nums.length; k++) {
if ((k > j + 1 && nums[k] == nums[k - 1]))
continue;
if ((nums[i] + nums[j] + nums[k] == 0)) {
List<Integer> inList = new ArrayList<Integer>();
inList.add(nums[i]);
inList.add(nums[j]);
inList.add(nums[k]);
outList.add(inList);
break;
}
}
}
}
return outList;
}

(因为只有在尾巴进行添加并无其他功能,所以采用ArrayList比较实惠和效率)

312测试用例超时:

[82597,-9243,…………此处省略N千个数字]

不想说话,让蠢人静静。。。。

————————————————————————智商分割线————————————————————————

参考答案:74ms——beats85.12%    时间复杂度O(N2)

    public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums); for (int i = 0; i < nums.length-2; i++) {
int left = i + 1;
int right = nums.length - 1;
if (i > 0 && nums[i] == nums[i - 1])
continue; // 去掉重复的起点
while (left < right) {
int sum = nums[left] + nums[right] + nums[i];
if (sum == 0) {
result.add(Arrays.asList(new Integer[]{nums[i], nums[left], nums[right]}));
while (left < right && nums[left] == nums[left + 1])
left++; // 去掉重复的左点
while (left < right && nums[right] == nums[right - 1])
right--; // 去掉重复的右点
right--; // 进入下一组左右点判断
left++;
} else if (sum > 0) {
right--; // sum>0 ,说明和过大了,需要变小,所以移动右边指针
} else {
left++; // 同理,需要变大,移动左指针
}
}
}
return result;
}

精髓在于:   (排序 + 去重) +  双指针移动相向定位

注意:不需要“重复的双胞胎数组”,所以是“组合”即Cn/m(从M个数里随机选出N个数有多少种情况)而不是排列An/m——考虑去重

   所查找的数之间具有一定的关联(本题为:和为0),那么就应该利用这个属性,而不是简单的进行搜索。

思路解析:

首先考虑数组遍历时去重:方法一:先将数组排好序,在遍历的时候与上一个进行比较,相同则直接进入下一个

            方法二:用容器Set——简单,但是同样需要排序,增加算法复杂度并且此题三个数操作不方便【在第一题TwoSum的后面有更新用Set的方法】。

            所以数组遍历去重在已排序的情况下优先采取方法一。

其次考虑降低多次循环算法复杂度:

            降低复杂度一般的途径就是利用已有的而未用到的条件将多余的步骤跳过或者删去!

            由于三个数是具有一个特点的:和为某个定值,这个条件只是用来判断了而并没有使用

            并且,由上个去重得知,后面使用的数组是已经排序好的

            此时仔细想想应该就能想到

    从两端使用两个指针相向移动,两端指针所指数之和如果小于目标值,只需要移动左边的指针,否则只需要移动右边的指针!!

     例如[1,1,1,4,5,7,8,8,9]中 定目标值为15,从两边开始,1+9为10,小于15,移动右边指针左移变成1+8只会更少,所以移动左边变成4+9以此类推。。

              妈耶!我想不到啊!

此时为两数定位,而题目中要找3个数

      ………………外嵌for循环!!!又回到了我的领域 ahhhhhhh~

分析搞定!

LeetCode第[15]题(Java):3Sum 标签:Array的更多相关文章

  1. LeetCode第[15]题(Java):3Sum (三数之和为目标值)——Medium

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c  ...

  2. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  3. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  4. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  5. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  6. LeetCode第[16]题(Java):3Sum Closest 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, find three integers in S such that the sum is closes ...

  7. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  8. LeetCode第[26]题(Java):Remove Duplicates from Sorted Array 标签:Array

    题目难度:Easy 题目: Given a sorted array, remove the duplicates in-place such that each element appear onl ...

  9. LeetCode第[11]题(Java):Container With Most Water 标签:Array

    题目难度:Medium Given n non-negative integers a1, a2, ..., an, where each represents a point at coordina ...

随机推荐

  1. Oracle集合操作

    在Oracle中提供了三种类型的集合操作: 并(UNION).交(INTERSECT).差(MINUS) UNION:将多个查询的结果组合到一个查询结果之中,并去掉反复值 UNION ALL:将多个查 ...

  2. HTML中在a标签中添加onclick事件

    1.链接的onclick 事件被先执行,其次是href属性下的动作; 2.假设链接中同时存在href 与onclick,如果想让href 属性下的动作不执行,onclick 必须得到一个false的返 ...

  3. --------------Hibernate学习(四) 多对一映射 和 一对多映射

    现实中有很多场景需要用到多对一或者一对多,比如上面这两个类图所展现出来的,一般情况下,一个部门会有多名员工,一名员工只在一个部门任职. 多对一关联映射 在上面的场景中,对于Employee来说,它跟D ...

  4. 深入理解计算机系统_3e 第八章家庭作业 CS:APP3e chapter 8 homework

    8.9 关于并行的定义我之前写过一篇文章,参考: 并发与并行的区别 The differences between Concurrency and Parallel +---------------- ...

  5. HTML5 Canvas:初始Canvas

    Canvas ,HTML 5中引入它,可以做很多事情:画图.动画.游戏开发等等. Canvas 元素 Canvas 中文翻译为:画布. <canvas id=”yourCanvasId” wid ...

  6. 使用Mybatis进行多表联查操作

    (1)增加一个测试数据库shop_order,sql语句如下: CREATE DATABASE `shop_order`; USE `shop_order`; CREATE TABLE `t_user ...

  7. C# Lock、Monitor避免死锁

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 微信小程序使用场景延伸:扫码登录、扫码支付

    微信小程序使用场景延伸:扫码登录.扫码支付 小程序最适合的使用场景有哪些?相比大家能列举出来很多,但这个场景,大家可能多数没想到_^ 笔者团队近期接到了一个PC项目:转转游戏租号PC官网,该项目要求在 ...

  9. iOS 多线程 简单学习NSThread NSOperation GCD

    1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...

  10. 基于CDH 5.9.1 搭建 Hive on Spark 及相关配置和调优

    Hive默认使用的计算框架是MapReduce,在我们使用Hive的时候通过写SQL语句,Hive会自动将SQL语句转化成MapReduce作业去执行,但是MapReduce的执行速度远差与Spark ...