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. LOJ#2076. 「JSOI2016」炸弹攻击(模拟退火)

    题面 传送门 题解 退火就好了 记得因为答案比较小,但是温度比较高,所以在算\(\exp\)的时候最好把相差的点数乘上一个常数来让选取更劣解的概率降低 话虽如此然而我自己打的退火答案永远是\(0\)- ...

  2. 喝最烈的酒、挖最大的DONG——工具与技巧篇

    本文作者:i春秋签约作家——黑色镰刀 0×00 前言 在这个科技发达的时代,很多时候工具都可以代替人做很多事情,之前我就有谈起过有企业将人工智能运用于网络安全方面,像如今,也有更多更人性化更智能的工具 ...

  3. Performs the analysis process on a text and return the tokens breakdown of the text

    Analyzeedit Performs the analysis process on a text and return the tokens breakdown of the text. Can ...

  4. 私有成员的设置和访问方式——setter和getter

    在定义类时,为了保证类中成员数据安全性及的封装性,防止成员数据值被任意修改,通常将类中成员属性用private进行修饰. 被private修改的成员属性,只能在类中访问,跳出本类后,就无法直接访问. ...

  5. [网络] DHCP 之 Mac 绑定

    [网络] DHCP 之 Mac 绑定 一.瞎扯 今天我们来简单聊聊Mac绑定,这在设备管理时常常被使用. 当然你可能会说我可以设置静态IP啊.先不提静态IP容易冲突.现在我在设置树莓派时就遇到一个问题 ...

  6. su: Authentication failure 的解决方案

    原因是:ubuntu默认不允许使用root登录,因此初始root账户是不能使用的,需要在普通账户下利用sudo权限修改root密码. 解决方案很简单:设置一个root密码就行了.注意是sudo 而不是 ...

  7. Spring注解大全,汇总版

    Spring使用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...

  8. mysql随机取出若干条记录的实用方法

    1.常见的方法 ; 这种方法可以随机取得数据,但是如果表比较大,数据量很多的时候会很耗时. 2.优化后的方式 ) as t ); 分析,首先根据条件筛选出要选的数据,然后随机排序取出要的条数的id , ...

  9. AssertJ断言系列<一>

    1 - Get AssertJ Core assertions Maven的pom.xml加入如下配置: <dependency> <groupId>org.assertj&l ...

  10. MySQL , MHA , Haproxy 配置

    1. 基本架构 2. 读端口影射 3. 写端口影射 进行一个Health Check MHA Manager对Master节点MySQL 进行存活监控 读FailOver 1 读FailOver 2 ...