一.题目

3Sum

Total Accepted: 45112 Total
Submissions: 267165My
Submissions

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:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.
    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
(-1, 0, 1)
(-1, -1, 2)
Show Tags
Have you met this question in a real interview?

Yes
No

Discuss
























二.解题技巧

    这道题和另外一道题Two Sum非常类似,只是这道题是在数组中寻找三个数,使得其和为0,同一时候要求这三个数仅仅能出现一次。假设单纯得使用暴力算法来做的话。时间复杂度为O(n^3)。且非常难推断这一组数是否已经出现过。
    假设考虑将数组A(元素个数为n)进行升序排序。那么依照顺序将数组中的第i个数作为三个数中最小的数。寻找从A的第i+1个数到n-1个数中满足和为-A[i]的数。就能够找到满足三个数和为0的组合了,可是,单独考虑这样的情况,会出现反复的问题。

要保证不出现反复的情况,当i!=0时,假设第i个数与第i-1个数同样的话,则不进行处理,直接处理第i+1个元素。这样。仅仅要保证三个数中最小的数是依照顺序递增的。那么算法找到的解就都是不反复的。

    这道题的边界条件在于:因为我们选择的是三个数中的最小值,因此。对于这个数的循环是[0, n-2)。同一时候,要对最小值进行消除反复的元素时。须要从第1个元素開始推断。假设从第0个元素開始推断的时候。可能会将0。0,0这样的情况忽略掉,因此,在消除反复的最小元素时,必须从第1个元素才開始。
    这道题在寻找数组A中的两个数的和为-A[i]时,能够考虑利用数组A是已经排序的条件,进行左右夹逼操作。在进行左右搜索的时候,须要将左右两边收缩到与当前元素不同的元素为止,这样做有两个原因:1.能够降低计算量;2.当当前的两个元素的和刚好等于-A[i]的时候,假设没有进行上面的缩放操作,那么就可能将反复的三个数保存下来,导致结果出错。



三.实现代码

class Solution
{
public:
vector<vector<int> > threeSum(vector<int> &num)
{
int Size = num.size(); vector<vector<int> > Result; if (Size < 3)
{
return Result;
} sort(num.begin(), num.end()); for (int Index_outter = 0; Index_outter < (Size - 2); Index_outter++)
{
int First = num[Index_outter];
int Second = num[Index_outter + 1];
const int Target = 0; if ((Index_outter != 0) && (First == num[Index_outter - 1]))
{
continue;
} int Start = Index_outter + 1;
int End = Size - 1; while (Start < End)
{
Second = num[Start];
int Third = num[End]; int Sum = First + Second + Third; if (Sum == Target)
{
vector<int> Tmp;
Tmp.push_back(First);
Tmp.push_back(Second);
Tmp.push_back(Third); Result.push_back(Tmp); Start++;
End--;
while (num[Start] == num[Start - 1])
{
Start++;
}
while (num[End] == num[End + 1])
{
End--;
} } if (Sum < Target)
{
Start++;
while (num[Start] == num[Start -1])
{
Start++;
}
} if (Sum > Target)
{
End--;
if (num[End] == num[End + 1])
{
End--;
}
} } }
return Result; }
};



四.体会

    我自己的想法时,将数组进行排序,然后依照顺序选择数组A[1, n-1)中的元素作为三个数中的中位数来在剩下的已经排好序的数组中寻找满足条件的其它两个数。可是。选择中位数的这样的情况须要考虑的边界条件比較复杂,并没有选择最小值来得方便一些。同一时候,选择中位数之后。将已经排序的数组分成了两段,这样在进行收缩的时候。须要分别推断两个两边与i的关系,也比較easy出错。

    这道题通过对数组进行排序。从而依照顺序选择不同的最小值来避免出现反复的情况。这确实是一个比較好的编程技巧。




版权全部,欢迎转载,转载请注明出处。谢谢



LeetCode_3Sum的更多相关文章

  1. LeetCode_3Sum Closest

    一.题目 3Sum Closest Total Accepted: 32191 Total Submissions: 119262My Submissions Given an array S of  ...

随机推荐

  1. 【LeetCode】Remove Nth Node From End of List(删除链表的倒数第N个节点)

    这道题是LeetCode里的第19道题. 题目要求: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, ...

  2. HDU 5536 Chip Factory

    Chip Factory Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)T ...

  3. 【JavaScript 3—基础知识点】:运算符

    导读:其实看到这个运算符的学习,很有一种熟悉感,因为在总体看来,和之前的C++有很多类似的地方,但当时觉得简单,没有总结.所以,这次一定得总结了.其实,知识的罗列,基础的积累,在学习中也很重要. 一. ...

  4. Ignite集成Spark之IgniteDataFrames

    下面简要地回顾一下在第一篇文章中所谈到的内容. Ignite是一个分布式的内存数据库.缓存和处理平台,为事务型.分析型和流式负载而设计,在保证扩展性的前提下提供了内存级的性能. Spark是一个流式数 ...

  5. 【2018.11.22】CTSC2018(模拟赛!)

    太蠢了……$noip$ 后第一次模拟赛竟然是这样的……完全就是打击自信 / 降智…… 1. 假面 一道神仙概率 $dp$!第一次写…… 拿到题就发现血量 $m_i$ 的上限只有 $100$! 然后 $ ...

  6. leetcode 349 map

    只需要用map来标记1,今儿通过map的值来得到重叠的部分 class Solution { public: vector<int> intersection(vector<int& ...

  7. springmvc接口接收json类型参数设置

    Springmvc需要如下配置: 1.开启注解 <!-- 开启注解--> <mvc:annotation-driven /> 2.加入相关bean <bean class ...

  8. 洛谷P2625 豪华游轮

    题目描述 有一条豪华游轮(其实就是条小木船),这种船可以执行4种指令: right X : 其中X是一个1到719的整数,这个命令使得船顺时针转动X度. left X : 其中X是一个1到719的整数 ...

  9. SLAVEOF以后

    当我们想要某个Redis服务器复制另一个服务器时,我们可以在连接这个Redis服务器的客户端上输入“SLAVEOF”命令指定另一个服务器的IP地址和端口号: SLAVEOF <master_ip ...

  10. Hdu5921 Binary Indexed Tree

    Hdu5921 Binary Indexed Tree 思路 计数问题,题目重点在于二进制下1的次数的统计,很多题解用了数位DP来辅助计算,定义g(i)表示i的二进制中1的个数, $ans = \su ...