题目在这里: https://leetcode.com/problems/3sum/

【标签】 Array; Two Pointers

【个人分析】

老实交待,这个题卡半天,第一次做不会,抄别人的。过了很久,第二次做,还是不会……。好几次都是Time Limited Error。在看过正确答案之后,才知道是用的Two Pointers + sort 做的优化。

  怎么优化? 简单说,就是通过 排序 + 跳过重复(利用Two Pointers) 来达到题目中避免 duplicates的要求。

  核心思路: 我们给最终的由3个数组成的小数组叫 triplet。

1. 先锁定triplet中的第一个数字的index为 i (Line 12),

2. 然后我们希望从 [ nums[i + 1], nums[end]] 中找到两个数字,使得两个数字的和为 (0 - nums[i])

  关键步骤:1. 在锁定第一个数字index的时候,跳过所有重复的数字 (Line 16处)。直到我们找到下一个不重复的数字作为triplet中的第一个数字

2. 在从[nums[i + 1], nums[end]]中找两个数字的时候,利用left pointer, right pointer。如果 left, right两个数的和比 twoSumTarget (Line 39)

小的话,只能通过将left pointer向右移动,来使得left + right的和更大一些,从而更接近twoSumTarget。

【一点心得】

  在O(N^2)的算法中,考虑加入O(NlgN) 的排序操作。特别是遇到需要去除重复的时候,利用排序 + Two Pointers 来达到 HashSet的效果。

 public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
int len = nums.length;
if (len < 3) {
return result;
} Arrays.sort(nums); // for all number that can be the 1st number of triplet
for (int i = 0; i < len - 1; i++) {
int firstNumber = nums[i]; // skip all duplicated first number
if (i == 0 || firstNumber != nums[i - 1]) { int leftIndex = i + 1;
int rightIndex = len - 1;
int twoSumTarget = 0 - firstNumber; // try to find two numbers that sum up to twoSumTarget
while (leftIndex < rightIndex) {
int twoSum = nums[leftIndex] + nums[rightIndex];
if (twoSum == twoSumTarget) {
// one valid triplet found!!
result.add(Arrays.asList(firstNumber, nums[leftIndex], nums[rightIndex]));
// skip duplicated nums[leftIndex]
while (leftIndex < rightIndex && nums[leftIndex] == nums[leftIndex + 1]) {
leftIndex++;
}
// skip duplicated nums[rightIndex]
while (leftIndex < rightIndex && nums[rightIndex] == nums[rightIndex - 1]) {
rightIndex--;
}
// move to next non-duplicates
leftIndex++;
rightIndex--;
} else if (twoSum < twoSumTarget) {
// move left towards right to
// make twoSum larger to get closer to twoSumTarget
leftIndex++;
} else {
rightIndex--;
}
} }
} return result;
}
}

[Leetcode][015] 3Sum (Java)的更多相关文章

  1. 【JAVA、C++】LeetCode 015 3Sum

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  2. [Leetcode]015. 3Sum

    public class Solution { public List<List<Integer>> threeSum(int[] num) { Arrays.sort(num ...

  3. [Leetcode][016] 3Sum Closest (Java)

    题目: https://leetcode.com/problems/3sum-closest/ [标签]Array; Two Pointers [个人分析] 这道题和它的姊妹题 3Sum 非常类似, ...

  4. [LeetCode] 259. 3Sum Smaller 三数之和较小值

    Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 < ...

  5. No.015 3Sum

    15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium Given an array S of n i ...

  6. 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)

    转自  http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...

  7. LeetCode 15 3Sum [sort] <c++>

    LeetCode 15 3Sum [sort] <c++> 给出一个一维数组,找出其中所有和为零的三元组(元素集相同的视作同一个三元组)的集合. C++ 先自己写了一发,虽然过了,但跑了3 ...

  8. LeetCode--No.015 3Sum

    15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium Given an array S of n i ...

  9. LeetCode 16. 3Sum Closest(最接近的三数之和)

    LeetCode 16. 3Sum Closest(最接近的三数之和)

随机推荐

  1. po 和 mo 的互相转换

    反编译 mo 文件成 po 文件 msgunfmt test.mo -o test.po 编码 po 文件为 mo 文件 msgfmt -o test.mo test.po 记着备用.

  2. 线性表链式存储方式的C语言实现

    /* 编译器:Dev-c++ 5.1.0 文件名:linkList3.cpp 代码版本号:1.0 时间:2015年9月24日11:34:16 */ #include <stdio.h> # ...

  3. HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 php

    参考来源:http://qq398705749.iteye.com/blog/963818 php中HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 1.REMOTE_ADD ...

  4. Linux查看一个文件夹大小

    1.Linux查看一个文件夹大小: du -sh /home/yangkun [yangkun@sg1 bin]$ du -sh /home/yangkun/ 164M /home/yangkun/ ...

  5. mysql 日期比较

    情景是:距离当前到期时间多少天 可以考虑当前系统时间加上某个天数后,与数据库的字段作比较 1.已知的时间>=CURDATE()+10 2.在数据的查询中,考虑到sql语句的优化问题,应减少通配符 ...

  6. python常用数据结构的常用操作

    作为基础练习吧.列表LIST,元组TUPLE,集合SET,字符串STRING等等,显示,增删,合并... #===========List===================== shoplist ...

  7. Android 利用Application对象存取公共数据

    本文章来给大家介绍Android 利用Application对象存取公共数据. Android系统在运行每一个程序应用的时候,都会创建一个Application对象,用于存储与整个应用相关的公共变量. ...

  8. linux c 之signal 和sigaction区别

    http://blog.csdn.net/muge0913/article/details/7331129 要对一个信号进行处理,就需要给出此信号发生时系统所调用的处理函数.可以对一个特定的信号(除去 ...

  9. sicily 1035. DNA matching

    题意:判断基因链是否匹配,匹配的双链数加1,并要标记,下次比较不能重用! 解法: 打擂台法 #include<iostream> #include<string> #inclu ...

  10. 【转】H264视频编码级别说明profile level Encoder

    版权声明:本文为博主原创文章,未经博主允许不得转载. 首先要阐明所谓的AVC其实就是H.264标准,是由ITU-T和ISO/IEC组成的联合视频组(JVT,Joint Video Team)一起开发的 ...