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类似,可是因为能够拥有反复键值所以在查找方面有些不同

  1. 直接找到每种键值的全部元素的第一个元素的游标

通过函数:lower_bound( const keytype& x ), upper_bound( const keytype& x ) 能够找到比指定键值x的小的键值的第一个元素和比指定键值x大的键值的第一个元素。返回值为该元素的游标。

细节:当到达键值x已经是最大时。upper_bound返回的是这个multimap的end游标。同理,当键值x已经是最小了,lower_bound返回的是这个multimap的begin游标。

  1. 指定某个键值,进行遍历

能够使用上面的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 &amp; 总结的更多相关文章

  1. [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 ...

  2. [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 ...

  3. leetcode — 4sum

    import java.util.Arrays; import java.util.HashSet; import java.util.Set; /** * Source : https://oj.l ...

  4. LeetCode 4Sum 4个数之和

    题意:这是继2sum和3sum之后的4sum,同理,也是找到所有4个元素序列,满足他们之和为target.以vector<vector<int>>来返回,也就是二维的,列长为4 ...

  5. 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 ...

  6. 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 ...

  7. leetcode 4sum python

    class Solution(object): def fourSum(self, nums, target): """ :type nums: List[int] :t ...

  8. 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 = ...

  9. 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 + ...

随机推荐

  1. having 与where 的异同点

    having 与where 的异同点: where针对表中的列发挥作用,查询数据 having对查询结果中的列发挥作用,筛选数据 #查询本店商品价格比市场价低多少钱,输出低200元以上的商品 ; // ...

  2. RHEL7-Samba共享测试

    Linux<----->windows之间共享 Samba使用2个进程 smb    ip之间的通信用smb  (tcp)       nmb    主机名之间的通信用nmb (netbi ...

  3. yum安装提示错误Thread/process failed: Thread died in Berkeley DB library

    问题描述: yum 安装更新提示 rpmdb: Thread/process failed: Thread died in Berkeley DB library 问题解决: 01.删除yum临时库文 ...

  4. Java用freemarker导出word

    概述 最近一个项目要导出word文档,折腾老半天,发现还是用freemarker的模板来搞比较方便省事,现总结一下关键步骤,供大家参考,这里是一个简单的试卷生成例子. 详细 代码下载:http://w ...

  5. Android拦截外拨电话

    拦截监听外拨的电话,并进行处理: 向外拨打电话时系统会发出一个有序广播,虽然该广播最终会被拔号器里的广播接收者所接收并实现电话拔打,但我们可以在广播传递给拔号广播接收者之前先得到该广播,然后清除传递给 ...

  6. ios中两个view动画切换

    @interface ViewController () @property(nonatomic,retain)UIView *redview; @property(nonatomic,retain) ...

  7. [转]nonlocal和global

    在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local).嵌套作用域(Enclosing function locals).全局作用域(Global).内置作用域(bui ...

  8. Tomcat之如何使用Nginx进行集群部署

    目录结构: contents structure [+] 1,为什么需要集群 2,如何使用Nginx部署tomcat集群 2.1,下载Nginx 2.2,在同一台电脑上部署多个Tomcat服务器 2. ...

  9. Postgresql 正则表达式

    在postgresql中使用正则表达式时需要使用关键字“~”,以表示该关键字之前的内容需匹配之后的正则表达式,若匹配规则不需要区分大小写,可以使用组合关键字“~*”: 相反,若需要查询不匹配这则表达式 ...

  10. RVM Ruby 管理工具

    1.RVM 简介 1.1 Ruby 简介 Ruby 是一种面向对象的脚本语言,简单易用,功能强大.能跨平台和可移植性好等等.其实就是种脚本语言. Ruby 的软件源使用的是亚马逊的云服务,国内网络环境 ...