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. RHEL7 在不同的环境中使用不同的网络配置文件

    比如,我们可以设置RHEL7 系统在公司时使用一个网卡配置文件:在家时则使用另外一个配置文件(可以根据不同的环境设置多个网卡配置文件). 网卡配置信息如下: [root@rhel7 ~]# nmcli ...

  2. PL/SQL12中文版

    PLSQL12,界面优化很不错,更加美观,直接集成中文语言!,更加艳丽 01.界面 02.注册码 注意:有能力的还是购买付费版的,付费是对软件的高度认可和支持 12.0.3.1821 64bit: 注 ...

  3. Centos6.x 设置终端超时, 加强用户密码策略

    1. 密码有效期, 密码长度 $ more /etc/login.defs # Password aging controls: # # PASS_MAX_DAYS Maximum number of ...

  4. 微信小程序云端解决方案探索之路

    小程序刚推出的时候,很多人都觉得它就是 H5,因为开发小程序的三大语言和 HTML.CSS.JS 是一脉相承的,即使改变了扩展名也改不了其实质. 那么小程序的实质到底是不是 H5 呢?经过我们的论证分 ...

  5. DOM,浏览器,javascript,html之间的关系

    来源于:https://github.com/hucheng91/myBlog/blob/master/web/dom/dom.md DOM定义 DOM可以以一种独立于平台和语言的方式访问和修改一个文 ...

  6. HBase Go客户端Row构造注意事项

    1. Hbase 的Go客户端语言使用方法 2. Hbase的Row使用注意事项 2.1. Row的前几个字段尽量散列 2.2. Row的排序是把所有Row中的字符做字典排序 我们最近在一个项目中使用 ...

  7. kafka和websocket实时数据推送

    需求 ​ 已有Kafka服务,通过kafka服务数据(GPS)落地到本地磁盘(以文本文件存储).现要根据echarts实现一个实时车辆的地图. 分析 前端实时展现:使用websocket技术,实现服务 ...

  8. Android开发环境内容汇总

     Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...

  9. android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器

    一.基础知识点学习  1.Android体系结构 如图所示,android 架构分为三层: (1)最底层是linux内核,主要是各种硬件的驱动,如相机驱动(Camera Driver),闪存驱动(Fl ...

  10. Mysql5.6 make 错误以及解决办法

    1.若make出现类似错误: CMake Error: CMake was unable to find a build program corresponding to "Unix Mak ...