题目: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.

For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
(-1, 0, 1)
(-1, -1, 2)

额外的要求是不能返回重复的triplets,返回的a,b,c的顺序要是非递减的。

解法一:首先想一下,三个数相加,要为0的话,如果不是都为0,那么至少有一个正数一个负数。可以从这一点出发,设置两个指针i和j,分别指向数组S的首尾,always保持numbers[i] <= 0 and numbers[j]>0。哦,对了,数组要先给它排序。然后判断numbers[i] + numbers[j]的符号,如果是大于0,我们就去数组负数部分search,反之去正数部分找。因为数组是sorted,search部分可以用binarySearch。代码如下:

 //Program Runtime: 784 milli secs
public static ArrayList<ArrayList<Integer>> threeSum(int[] num) {
// Start typing your Java solution below
// DO NOT write main() function
Arrays.sort(num);
int i = 0;
int j = num.length - 1;
int firstNonNegativeIndex = -1;
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(j < 0 || num[i] > 0 || num[j] < 0) return result;//1.边界条件判断,如果没有非负数或者都是正数,返回空集合
for(int k = 0; k < num.length;k++){
if(num[k] >= 0){
firstNonNegativeIndex = k;
break;
}
}
for(i = 0;i <= firstNonNegativeIndex;i++){
if(i > 0 && num[i] == num[i-1])continue;
for(j = num.length - 1; j> i + 1;j--) {
if(j <= num.length - 2 && num[j + 1] == num[j]) continue;
int twoSum = num[i] + num[j];
if(twoSum > 0) {
int searchIdx = binarySearch(num, i+1,firstNonNegativeIndex - 1, -twoSum);
if(searchIdx != -1){
addTuple(result,new int[]{num[i],num[searchIdx],num[j]});
}
}else{
int searchIdx = binarySearch(num, firstNonNegativeIndex,j-1, -twoSum);
if(searchIdx != -1){
addTuple(result,new int[]{num[i],num[searchIdx],num[j]});
}
}
}
}
return result;
}

O(n^2logn)

这里要注意一些边界条件的判断。

1.如果是空数组,或者均是整数或均是负数,返回空集合;

2.在遍历i和j的时候,为满足题设“不能返回重复的triplets”,遇到和前一个相同的i或者后一个相同的j,continue。

虽然能通过大集合,但该解法并不是最好的。

解法二这里提到一个O(n2)的解法。首先(当然最首先的还是要排序数组),固定i(for i from 0 to last)。对每个i,有j=i+1,k=last。对三者取和,如果大于0,说明k的那边取大了,k向前移动;如果小于0呢,说明j取得太小了,向后移动。如果等于0,记录i,j,k并同时移动j和k。

 public static ArrayList<ArrayList<Integer>> threeSum2(int[] num) {
Arrays.sort(num);
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
for(int i = 0; i < num.length - 2;i++){
if(i > 0 && num[i] == num[i-1])continue;
int j = i + 1;
int k = num.length - 1;
while(j < k){
int twoSum = num[i] + num[j];
if(twoSum + num[k] > 0){
k--;
}else if(twoSum + num[k] < 0){
j++;
}else {
addTuple(result,new int[]{num[i],num[j],num[k]});
j++;
k--;
while(num[j] == num[j - 1] && num[k]==num[k+1] && j < k){
j++;
k--;
}
}
}
}
return result;
}

O(n^2)

这道虽然不是那么难,但是要注意的是边界条件的判断和代码的简洁;排序是个好东西。

解法二这种,还可以应用到4Sum,3SumCloset问题中。想对于穷举法,是一种“有计划”的搜索问题。

LeetCode 笔记系列三 3Sum的更多相关文章

  1. LeetCode 笔记系列 18 Maximal Rectangle [学以致用]

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones ...

  2. Python基础笔记系列三:list列表

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python中的list列表是一种序列型数据类型,一有序数据集合用逗号间隔 ...

  3. LeetCode 笔记系列16.3 Minimum Window Substring [从O(N*M), O(NlogM)到O(N),人生就是一场不停的战斗]

    题目:Given a string S and a string T, find the minimum window in S which will contain all the characte ...

  4. LeetCode 笔记系列16.1 Minimum Window Substring [从O(N*M), O(NlogM)到O(N),人生就是一场不停的战斗]

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

  5. LeetCode 笔记系列八 Longest Valid Parentheses [lich你又想多了]

    题目:Given a string containing just the characters '(' and ')', find the length of the longest valid ( ...

  6. LeetCode 笔记系列13 Jump Game II [去掉不必要的计算]

    题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...

  7. Java基础复习笔记系列 三

    前几节都是基础中的基础,从第三讲的笔记开始,每次笔记针对Java的一个知识块儿.  Java异常处理 1.什么是异常? 异常是指运行期出的错误.比如说:除以一个0:数组越界:读取的文件不存在. 异常处 ...

  8. LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]

    题目:Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...

  9. Android群英传笔记系列三 view的自定义:实现一个模拟下载

    1.实现效果:动态显示进度(分别显示了整个的动态改变的过程,然后完成后,弹出一个对话框)       2.实现过程:可以分为绘制一个圆,圆弧和文本三部分,然后在MainAcitivity中通过线程模拟 ...

随机推荐

  1. 分享一个mysql 复杂查询的例子

    发布:脚本学堂/MySQL  编辑:thebaby   2013-08-23 09:37:37  [大 中 小] 有关mysql复杂查询的一个例子,正在学习mysql的朋友,可以作为一个参考. 在my ...

  2. DPDK 全面分析

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 高性能网络技术 ...

  3. jsp学习之scriptlet的使用方法

    scriptlet的使用 jsp页面中分三种scriptlet: 第一种:<%  %>  可以在里面写java的代码.定义java变量以及书写java语句. 第二种:<%! %> ...

  4. 记一次处理IE引起的上网异常处理

    win7 64bit系统,IE(11)出问题.在更新记录里找不到IE11的更新项,也就无法通过正常卸载了.而网上的各种折腾卸载方式均宣告无效.后来无意间找到了一款国外大神开发的软件:RemoveIE, ...

  5. [转]JavaScript放在<head>和<body>的区别

    原文:http://liminhappygirl.iteye.com/blog/1841360 javaScript放在<head>和<body>的区别: 在HTML body ...

  6. centos IPTables 配置方法

    entos IPTables 配置方法 http://os.51cto.com/art/201103/249359_1.htm iptables 指南 1.1.19 http://www.frozen ...

  7. response.setHeader各种用法

    一秒刷新页面一次 response.setHeader("refresh","1"); 二秒跳到其他页面 (登陆跳转) response.setHeader(& ...

  8. jquery头文件的引入

    <script type="text/javascript" src="/library/js/jquery/jquery-1.9.1.min.js"&g ...

  9. spark读取gz文件

    spark 1.5.1是支持直接读取gz格式的压缩包的,和普通文件没有什么区别: 使用spark-shell进入spark shell 交互界面: 输入命令: sc.textFile("\h ...

  10. ubuntu 12.04下apache 配置家目录地址

    apache2 最在搞前端相关的东西,上一次也记录了 Linux 下 LAMP环境的搭建,现在记录一下如果改变 apache2 的家目录地址该怎么做,改那个配置文件 修改配置文件 /etc/apach ...