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. 《快学Scala》第五章 类

    关于case class和普通class的区别,可以参考: https://www.iteblog.com/archives/1508.html

  2. redhat linux elk命令

    安装es后不能启动原因在elasticsearch.yml中加如下两个配置: bootstrap.memory_lock: falsebootstrap.system_call_filter: fal ...

  3. LeetCode 795. Number of Subarrays with Bounded Maximum

    问题链接 LeetCode 795 题目解析 给定一个数组A,左右范围L.R.求子数组的数量,要求:子数组最大值在L.R之间. 解题思路 子数组必须连续,利用最大值R对数组进行分段,设定变量 left ...

  4. 2016级算法期末模拟练习赛-F.AlvinZH的青春记忆IV

    1086 AlvinZH的青春记忆IV 思路 难题,动态规划. 这是一道很有意思的题,因为它不仅卡了时间,也卡了空间,而且卡的很妙很迷. 光是理解题意已经有点难度,简化题意:两串数字序列,相等的数字定 ...

  5. ubuntu下安装ffmpeg

    sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next sudo apt-get update sudo apt-get install ff ...

  6. 南昌 Max answer

    https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a interva ...

  7. Mac 10.12安装流量监控软件Magican

    说明:Magican这家公司已经不维护了,但是软件是单机版的,可以正常使用,但是有些10.12的机器应该是无法看到每个进程的明细,总速度可以正常显示. 下载: (链接: https://pan.bai ...

  8. suse-Linux下安装Oracle11g服务器

    系统要求 Linux安装Oracle系统要求 系统要求 说明 内存 必须高于1G的物理内存 交换空间 一般为内存的2倍,例如:1G的内存可以设置swap 分区为3G大小 硬盘 5G以上 2.修改操作系 ...

  9. unity批量设置图片为etc2格式或者astc格式

    网上找了半天,没一个能用的,干脆自己写个,直接拷贝这个脚本就行 这个是ios版本的,安卓的话写在注释里面,去掉注释就能用了 现在ios支持一种新格式叫astc比原本的pvrtc压缩比更高,而且质量更高 ...

  10. spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)

    首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...