题目: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. C#删除xml指定节点

  2. mysql innodb的重要组件

    innodb包涵如下几个组件 一.innodb_buffer_pool: 1 它主要用来缓存数据与索引(准确的讲由于innodb中的表是由聚集索引组织的,所以数据只不是过主键这个索引的叶子结点). 二 ...

  3. unity5, 在unity中编辑动画

    如图,dock是一个空gameObject,其下包含mouth_dn,mouth_up (应该叫lip_dn,lip_up更合适,这不是重点,先不改了),head,eye_left,eye_right ...

  4. AntShares区块链的节点部署与搭建私有链

    近期陆续体验常见的区块链开源项目,比如小蚁OnChain出的AntShares.AntShares跟其它开源区块链项目不一样,他们家是使用C#开发,基于.NET Core执行在Linux,期待未来出G ...

  5. ruby gem tips(转)

    淘宝源: https://ruby.taobao.org 升级ruby gem gem update --system 查看gem版本 gem -v 查看gem版本,gems安装目录,remote s ...

  6. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

  7. 使用模板方法模式简化JDBC操作

    在使用JDBC时,会重复的写很多重复的代码,例如 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; S ...

  8. Android——Bundle savedInstanceState的作用

    写过Android程序的都知道Activity中有一个名称叫onCreate的方法.该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始.可是有一点容易被忽视,就是onCr ...

  9. zabbix监控数据库

    Zabbix通过percona监控MySQL   因为Zabbix自带的MySQL监控没有提供可以直接使用的Key,所以一般不采用,业界的同学们都使用Percona Monitoring Plugin ...

  10. C#读取EXECL关键代码

    string strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + ";Extend ...