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. centos7修改静态ip地址

    今天逛园的时候突然发现这篇有关网络参数修改的文章写的很好,简单又使用,格式也很好的,所以就引用过来了. http://www.cnblogs.com/hongdada/p/6666932.html

  2. 服务器变量 $_SERVER 详解

    摘抄:http://ha.cker.in/942.seo 1.$_SESSION[‘PHP_SELF’] — 获取当前正在执行脚本的文件名 2.$_SERVER[‘SERVER_PROTOCOL’] ...

  3. BruteXSS(汉化版)

    BruteXSS是一个非常强大和快速的跨站点脚本暴力注入.它用于暴力注入一个参数.该BruteXSS从指定的词库加载多种有效载荷进行注入并且使用指定的载荷和扫描检查这些参数很容易受到XSS漏洞.得益于 ...

  4. JMeter PerfMon Metrics Collector性能监控插件

    官方文档地址https://jmeter-plugins.org/wiki/PerfMon/ JMeter是一款压力测试工具,我们也可以用它来监控服务器资源使用情况. JMeter正常自带可以通过To ...

  5. docker微服务部署之:二、搭建文章微服务项目

    docker微服务部署之:一,搭建Eureka微服务项目 一.新增demo_article模块,并编写代码 右键demo_parent->new->Module->Maven,选择M ...

  6. 2016级算法第六次上机-B.ModricWang's FFT : EASY VERSION

    1114 ModricWang's FFT EASY VERSION 思路 利用FFT做大整数乘法,实际上是把大整数变成多项式,然后做多项式乘法. 例如,对于\(1234\),改写成\(f(x)=1* ...

  7. QuantLib 金融计算——收益率曲线之构建曲线(2)

    目录 QuantLib 金融计算--收益率曲线之构建曲线(2) YieldTermStructure 问题描述 Piecewise** 分段收益率曲线的原理 Piecewise** 对象的构造 Fit ...

  8. 集合之六:Map接口

    Map接口概述 Map接口中的集合和Collection接口中的集合在存储数据的格式上有很大的不同,Map接口下的内容是以<K , V> ,键值对的形式存储的,我们查询API,Map接口的 ...

  9. [ZJOI2019]Minimax搜索

    先求出根节点的权值\(w\).根据套路,我们对于每个\(k\),计算\(w(s)\leq k\)的方案数,差分得到答案.为了方便,接下来考虑计算概率而不是方案数. 可以发现,对于一个给定的有解的子集, ...

  10. express后端和fetch前端的json数据传递

    在使用express做后端,前端使用fetch API来请求后端时,一般都是用 JSON 数据进行通信的. 下面是一个简单的例子: 前端: if (up) { var passwordAgain = ...