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. python之模块pprint之常见用法

    # -*- coding: cp936 -*- #python 27 #xiaodeng #python之模块pprint之常见用法 import pprint data = [(1,{'a':'A' ...

  2. HP ALM lis

    <?xml version="1.0" encoding="UTF-8"?><license version="1.0"& ...

  3. 关于CASE WHEN的多条件汇总问题

    https://bbs.csdn.net/topics/392217817?page=1 问题: --创建测试表 IF EXISTS (SELECT * FROM sys.objects WHERE ...

  4. Vue.js——60分钟快速入门 开发· webpack 中文文档

    转载于:http://www.cnblogs.com/keepfool/p/5619070.html http://www.css88.com/doc/webpack2/guides/get-star ...

  5. Jquery UI的日历控件datepicker限制日期(转)

    网上找到这篇文章:http://www.jssay.com/blog/index.php/2010/04/27/%E5%A6%82%E4%BD%95%E7%A6%81%E7%94%A8datepick ...

  6. 【Struts2】Struts2与Spring整合后,如何指定Action为多例模式

    Strust2默认是多例的,但是Spring默认是单例的,在进行Spring+Strust2整合的时候,就需要把Spring管理的action指定为多例模式,只需要在action上面加上@Scope( ...

  7. jQuery.ajax发送image请求格式

    1\请求端 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head run ...

  8. Android Studio 遇到 No Debuggable Applications 的解决方案

    一.在菜单的Tools -> Android -> 勾选 Enable ADB Integration 二.在工程的build.gradle(Module:app)里加上一行代码

  9. Mapped Statements collection does not contain value for com.xxxx.dao.impl.AreaDAOImpl.findByCode

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.Persiste ...

  10. stm32定时器PWM模式和输出比较模式

    pwm模式是输出比较模式的一种特例,包含于输出比较模式中 /** @defgroup TIM_Output_Compare_and_PWM_modes * @{ */ #define TIM_OCMo ...