Three Sum:

Given an array S of n integers, are there elements a, b, c 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.

这是一道LeetCode中标记为Medium的题。由于时间限制,对算法的复杂度有要求,最后的解法确实有点巧妙。

给一个有n个数字的数组S,找出所有满足a + b + c = 0的组合,结果排除重复元组。

最初的错误尝试

一开始的想法是,先将数组排序,通过三次遍历找出所有a、b、c的组合,再排除相同的元组。这个算法的复杂度在元组很少时是O(n^3),元组很多的时更大,在输入很长的时候就超时了。

接下来还是想在这个的基础上改良——将n缩小。

在某些时候——例如-3,-2,0,2,6,8,由于6和8比最小的两个数加起来还大,所以可以舍去不考虑。同理,在例如-5,0,1,2的数列中-5也可以不考虑。这样就减少了计算量。但是最后依然超时。

在复杂度至少是O(n^3)的算法上的改良尝试失败。我在过去做题遇到超时时,曾经做过很多次这种尝试,但是每次都失败了。改进算法还是要做到在O层面降低复杂度才行。

要找到一种复杂度Ω(n^3)的算法才有机会通过。

解决方案

在参考了LeetCode的Discussion之后,有了最后的解决方案。

这种解决方案参考了题目Two Sum的解法,复杂度只有O(n^2)

class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> re;
sort(nums.begin(), nums.end());
//当nums中元素个数不足3个时,返回一个空的re就可以了
if(nums.size() < 3){
return re;
}
for(int i = 0 ; i < nums.size() - 1 ; i++){
int target = nums[i];
int font = i + 1;
int back = nums.size()-1;
while(back > font){ //由于nums已经被排序,所以
//如果三个数之和小于0,那么让font++,下一次检测三个数之和就会增大(也可能不变)
//如果三个数之和大于0,那么让back--,下一次检测三个数之和就会减小(也可能不变)
if(target + nums[font] + nums[back] < 0){
font ++;
}
else if(target + nums[font] + nums[back] > 0){
back --;
} //等于0的时候添加到re中
else if(target + nums[font] + nums[back] == 0 && font <back){
vector<int> temp;
temp.push_back(-target);
temp.push_back(nums[font]);
temp.push_back(nums[back]);
re.push_back(temp); //此时要让font和back分别自增、自减到下一个不同的数字
while(nums[font] == temp[1] && font <back){
font ++;
}
while(nums[back] == temp[2] && font <back){
back --;
}
}
} //让target自增到下一个不同的数字
while(i<nums.size()-1 && nums[i] == nums[i+1]){
i++;
}
}
return re;
}
};

在这个算法里,最重要的是只用了两个循环就检测出所有abc元组。

其次,通过两次让font和back、target自增(自减)到下一个不同的数字,就排除了重复元组。

[LeetCode] Three Sum题解的更多相关文章

  1. [LeetCode]Combination Sum题解(DFS)

    Combination Sum Given a set of candidate numbers (C) (without duplicates) and a target number (T), f ...

  2. LeetCode:Path Sum I II

    LeetCode:Path Sum Given a binary tree and a sum, determine if the tree has a root-to-leaf path such ...

  3. 剑指offer 65. 不用加减乘除做加法(Leetcode 371. Sum of Two Integers)

    剑指offer 65. 不用加减乘除做加法(Leetcode 371. Sum of Two Integers) https://leetcode.com/problems/sum-of-two-in ...

  4. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...

  5. LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表

    文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...

  6. [LeetCode] Range Sum Query - Mutable 题解

    题目 题目 思路 一看就是单点更新和区间求和,故用线段树做. 一开始没搞清楚,题目给定的i是从0开始还是从1开始,还以为是从1开始,导致后面把下标都改掉了,还有用区间更新的代码去实现单点更新,虽然两者 ...

  7. LeetCode Two Sum&Two Sum II - Input array is sorted&3Sum&4Sum 一锅煮题解

    文章目录 Two Sum Two Sum II 3Sum 4Sum Two Sum 题意 给定一个数组,和指定一个目标和.从数组中选择两个数满足和为目标和.保证有且只有一个解.每个元素只可以用一次. ...

  8. LeetCode Two Sum II - Input array is sorted

    原题链接在这里:https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/ 题目: Given an array of intege ...

  9. LeetCode Two Sum III - Data structure design

    原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...

随机推荐

  1. Linux 中使用 virsh 管理 KVM 虚拟机 (转)

    术语 虚拟化指的是:在相同的物理(硬件)系统上,同时运行多个操作系统,且这几个系统相互隔离的可能性,而那个硬件在虚拟化架构中被称作宿主机(host).虚拟机监视器(也被称为虚拟机管理程序(hyperv ...

  2. Linux修改profile文件改错了,恢复的方法

    Linux修改profile文件改错了,恢复的方法在改profile的时候,改出问题了,除了cd以外的命令基本都不能用了,连vi都不能用了,上网查了下,用export PATH=/usr/bin:/u ...

  3. v-bind、v-on 的缩写

    Vue中的缩写:v-bind.v-on v-bind 缩写:: 预期:any (with argument) | Object (without argument) 参数:attrOrProp (op ...

  4. 将python的代码文件打包成可执行文件

    1.使用pip install Pyinstaller  命令安装 2.使用命令 pyinstaller -F  *.py打包成exe 3.在\dist文件夹下找到exe; 一.pyinstaller ...

  5. Unity脚本生命周期与执行顺序

    文章目录 脚本生命周期 MonoBehavior生命周期图 脚本执行顺序 自定义执行顺序 在Unity中,脚本可以理解为附加在游戏对象上的用于定义游戏对象行为的指令代码.必须绑定在游戏对象上才能开始它 ...

  6. Mac系统升级至OS X Mavericks后Genymotion出现的问题及解决方法

    Apple的系统升级终于免费了,可开心满满地升级到OS X Mavericks后,Android模拟器之王Genymotion罢工了.遇到两个问题:1. Unable to load VirtualB ...

  7. (热死你)Resin https ssl Linux 配置,实战可用

    (热死你)Resin https ssl Linux 配置,实战可用 一.配置resin 1.在resin服务器中创建目录keys文件和openssl.conf,格式内容如下: #先复制以下的内容: ...

  8. Java NIO开发需要注意的陷阱(转)

    陷阱1:处理事件忘记移除key在select返回值大于0的情况下,循环处理Selector.selectedKeys集合,每处理一个必须从Set中移除 Iterator<SelectionKey ...

  9. Java异常机制关键字总结,及throws 和 throw 的区别

    在Java的异常机制中,时常出现五个关键字:try , catch , throw , throws , finally. 下面将总结各个关键字的用法,以及throw和throws的区别: (1) t ...

  10. 用sql语句导出oracle中的存储过程和函数

    用sql语句导出oracle中的存储过程和函数: SET echo off ; SET heading off ; SET feedback off ; SPOOL 'C:/PRC.SQL' repl ...