LeetCode——4Sum & 总结
LeetCode——4Sum & 总结
前言
有人对 Leetcode 上 2Sum,3Sum,4Sum,K Sum问题作了总结:
http://blog.csdn.net/nanjunxiao/article/details/12524405
对于同类问题做了代码模型:
int i = starting; //头指针
int j = num.size() - 1; //尾指针
while(i < j) {
int sum = num[i] + num[j];
if(sum == target) {
store num[i] and num[j] somewhere;
if(we need only one such pair of numbers)
break;
otherwise
do ++i, --j;
}
else if(sum < target)
++i;
else
--j;
}
题目
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
Find all unique quadruplets in the array which gives the sum of target.
Note:
• Elements in a quadruplet (a, b, c, d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
• Thesolutionsetmustnotcontainduplicatequadruplets.For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)
思路
关于这道有很多解法:
解法一:K Sum
// 先排序,然后左右夹逼,时间复杂度 O(n^3),空间复杂度 O(1) class Solution {
public:
vector<vector<int>> fourSum(vector<int>& num, int target) {
vector<vector<int>> result;
if (num.size() < 4) return result;
sort(num.begin(), num.end());
auto last = num.end();
for (auto a = num.begin(); a < prev(last, 3); ++a) {
for (auto b = next(a); b < prev(last, 2); ++b) {
auto c = next(b);
auto d = prev(last);
while (c < d) {
if (*a + *b + *c + *d < target) {
++c;
 } else if (*a + *b + *c + *d > target) {
--d;
} else {
result.push_back({ *a, *b, *c, *d });
++c;
--d;
} }
} }
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());
return result;
} };
补充: 关于unique()去重的使用,
參考 http://blog.csdn.net/zlhy_/article/details/8784553
解法二:Hashmap
用一个 hashmap 先缓存两个数的和, 以及vector<int, int>
存这两个数。
在用两个游标遍历序列。key = target -v[x]-v[y], 依据 map.find(key), 找出另外两个数。
时间复杂度,平均 O(n^2),最坏 O(n^4),空间复杂度 O(n^2)
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &sums, int target) {
vector<vector<int> > result;
if (nums.size() < 4) return result;
sort(nums.begin(), num.end());
unordered_map<int, vector<pair<int, int> > > cache;
for (int i=0; i<nums.size(); ++i) {
for (int j=i+1; j<nums.size(); ++j){
cache[nums[i]+num[j]].push_back(pair<int, int>(i, j));
}
}
for (int x=0; x<nums.size(); ++x) {
for (int y=x+1; y<nums.size(); ++y) {
int key = target - nums[x] - nums[y];
if (cache.find(key) == cache.end()) continue;
vector<pair<int, int> > vec = cache[key];
for (int k=0; k<vec.size(); ++k) {
if (x <= vec[k].second)
continue; //有重叠
result.push_back({ nums[vec[k].first], nums[vec[k].second], nums[c], nums[d]});
}
}
}
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());
return result;
}
};
解法三:Multimap
首先要说的是 multimap的概念。
multimap提供了能够一种能够有反复键值的STL map类型。其插入方式和map类似,可是因为能够拥有反复键值所以在查找方面有些不同
- 直接找到每种键值的全部元素的第一个元素的游标
通过函数:lower_bound( const keytype& x ), upper_bound( const keytype& x ) 能够找到比指定键值x的小的键值的第一个元素和比指定键值x大的键值的第一个元素。返回值为该元素的游标。
细节:当到达键值x已经是最大时。upper_bound返回的是这个multimap的end游标。同理,当键值x已经是最小了,lower_bound返回的是这个multimap的begin游标。
- 指定某个键值,进行遍历
能够使用上面的lower_bound和upper_bound函数进行游历。也能够使用函数equal_range。其返回的是一个游标对。游标对pair::first是由函数lower_bound得到的x的前一个值,游标对pair::second的值是由函数upper_bound得到的x的后一个值。
这个算法的 时间复杂度 O(n^2),空间复杂度 O(n^2)
#include <iostream>
#include <vector>
#include <unordered_multimap>
using namespace std;
class Solution {
public:
vector<vector<int> > fourSum(vector<int>& num, int target) {
vector<vector<int> > result;
if (num.size()<4) return result;
sort(num.begin(), num.end());
unordered_multimap<int, pair<int, int>> cache;
for (int i=0; i+1<num.size(); ++i) {
for (int j=i+1; j<num.size(); ++j){
cache.insert(make_pair(num[i]+num[j], make_pair(i, j)));
}
}
for (pair i =cache.begin(); i!=cache.end(); ++i){
int x = target - a->first;
pair range = cache.equal_range(x);
for (pair j = range.first; j!=range.second; ++j) {
int a = i->second.first;
int b = i->second.second;
int c = j->second.first;
int d = j->second.second;
if (a != c && a != d && b != c && b != d) {
vector<int> vec = { num[a], num[b], num[c], num[d] };
sort(vec.begin(), vec.end());
result.push_back(vec);
}
}
}
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());
return result;
}
};
LeetCode——4Sum & 总结的更多相关文章
- [LeetCode] 4Sum II 四数之和之二
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...
- [LeetCode] 4Sum 四数之和
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...
- leetcode — 4sum
import java.util.Arrays; import java.util.HashSet; import java.util.Set; /** * Source : https://oj.l ...
- LeetCode 4Sum 4个数之和
题意:这是继2sum和3sum之后的4sum,同理,也是找到所有4个元素序列,满足他们之和为target.以vector<vector<int>>来返回,也就是二维的,列长为4 ...
- Leetcode 4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...
- Leetcode: 4Sum II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...
- leetcode 4sum python
class Solution(object): def fourSum(self, nums, target): """ :type nums: List[int] :t ...
- LeetCode 4Sum (Two pointers)
题意 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...
- LeetCode——4Sum
1. Question Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + ...
随机推荐
- 查询后n条记录
查询后n条记录 SELECT * FROM tb_stu ORDER BY id ASC LIMIT n
- linux rpm 安装后 mysql 默认安装目录等信息
MySQL安装完成后不象SQL Server默认安装在一个目录,它的数据库文件.配置文件和命令文件分别在不同的目录,了解这些目录非常重要,尤其对于Linux的初学者,因为 Linux本身的目录结构就比 ...
- Path画直线与弧线
代码地址如下:http://www.demodashi.com/demo/14754.html 前言 之前讲过Paint和Canvas的基本使用,今天来介绍下Path的使用 涉及内容有: Path画直 ...
- 使用Docker运行Java Web应用
前言 Tomcat是目前比较流行的Web应用服务器,深受Java爱好者的喜爱.通常J2EE应用的产出物是一个war包,这篇文章将为你介绍如何使用Docker运行Tomcat+war包的Java Web ...
- Apk反编译助手
Android是一个让人很纠结的产品,它开源开放,但是也有很多蛋疼坑爹的地方,还是那句话,谁开发谁知道! Apk反编译助手,懒人和对command line无爱的同学们可下载看看,至少需要.net 2 ...
- kubernetes-pod分配CPU和RAM资源以及计算方法
例子: Containers: cpu-ram-demo-container: ... image: busybox:latest resources: Limits: cpu: 1 memory: ...
- db_table--Spring Security3.1 最新配置实例
2011-04-28 这几天学习了一下Spring Security3.1,从官网下载了Spring Security3.1版本进行练习,经过多次尝试才摸清了其中的一些原理.本人不才,希望能帮助大家. ...
- 20 道 Spring Boot 面试题
转自:微信公众号:Java技术栈(id: javastack) 面试了一些人,简历上都说自己熟悉 Spring Boot, 或者说正在学习 Spring Boot,一问他们时,都只停留在简单的使用阶段 ...
- git 错误信息 6 uncommitted changes would be overwritten by merge
表示本地库有几个文件修改没有提交,说明本地有几个文件没有跟踪
- Octave及其工具包的安装
Octave的安装: http://blog.sina.com.cn/s/blog_1358485f70102wmpa.html http://www.gnu.org/software/octave/ ...