Given an array S of n integers, are there elements abc, 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)
  • The solution set must not contain duplicate quadruplets.
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)

在Leetcode中,除了4Sum以外,还有3Sum以及2Sum,有兴趣的朋友可以点击链接参考。

一、解题思路1:

在3Sum以及2Sum的基础上,可以总结出KSum的通用算法,那就是数组中按序挑选数字作为target(o(n)),对于余下的序列使用(K-1)Sum算法,其中2Sum的复杂度是o(n);

二、针对4Sum的解题思路2:

1、4Sum可以分解为2Sum+2Sum;因此将原始数组中,所有数字两两求和,记录在hash表;那么原来的4Sum=target的问题,就转为从hash表中找到2个Item使其Sum之和为target的问题;满足一个值的item可能有多种组合存在(如题目中的例子item=0,那么(-1,1)(-2,2)(0,0)都应保存在此item下),因此hash表可以将键值作为item值,而将value设为一个list,保存所有满足的组合。

2、如何操作hash表:

  我们可以倒过来思考,假设A+B+C+D=target,ABCD各不相同;由于hash表保存了所有元素两两之和的结果,即AB、AC、AD、BC、BD、CD都单独存在表中,如果仅仅寻找和为target的item组合的话,一共有AB+CD、AC+BD、AD+BC、BC+AD、BD+AC、CD+AB 6种情况满足和为target,但是他们都只对应一种返回值(A、B、C、D);

  为了避免出现6次重复结果,由于一个item中(例AC、BD)两个元素的排列顺序也是按照从小到大有序排列,因此我们只针对AB+CD的情况筛选。即如果两个item的和等与target,同时要满足item1的第二个值B要小于item2的第一个元素C,那么可以当做结果录入返回队列中,否则当做不符合要求。

3、除了以上措施避免重复之外,由于数组队列中存在重复的元素,并且第一轮建立hash表时不会对重复元素筛选剔除。因此要注意不要将某一值计算两次;

时间复杂度:

第一部分建立hash表需要n(n-1)/2,假设两两和值有x个,每个值平均有k种组合,那么x*k = n(n-1)/2;

所以程序时间复杂度为 o( n(n-1)/2 + x*k*k ) = o( n(n-1)/2 * (1+k) ),即时间复杂度约为o(kn2) ,k取值: 1~n(n-1)/2;

最好的情况是两两和值没有重复,x=n(n-1)/2,k=1;那么程序时间复杂度为o(n2);

最坏的情况是数组中所有元素都相等,那么x=1,k=n(n-1)/2,时间复杂度接近o(n4);

AC代码:

 class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > ret;
unordered_map<int, vector<pair<int, int> > > hmap;
sort(num.begin(), num.end());
int size = num.size(); for (int i = ; i < size - ; ++i) {
for (int j = i + ; j < size; ++j) {
hmap[num[i]+num[j]].push_back(make_pair(i, j));
}
} unordered_map<int, vector<pair<int, int> > >::iterator itr;
for (itr = hmap.begin(); itr != hmap.end(); ++itr) {
int new_target = target - itr->first;
if (hmap.find(new_target) == hmap.end())
continue;
vector<pair<int, int> > group1 = itr->second;
vector<pair<int, int> > group2 = hmap[new_target]; for (int i = group1.size() - ; i >= ; --i) {
if (i == group1.size() - || num[group1[i].first] != num[group1[i+].first]) {
for (int j = ; j < group2.size(); ++j) {
if (group2[j].second < group1[i].first &&
(j == || num[group2[j].first] != num[group2[j-].first])) {
vector<int> one_res {num[group2[j].first],
num[group2[j].second],
num[group1[i].first],
num[group1[i].second]};
ret.push_back(one_res);
}
}
}
}
} return ret;
}
};

附录:

C++ Hash表操作;

												

【Leetcode】【Medium】4Sum的更多相关文章

  1. 【LeetCode题意分析&解答】40. Combination Sum II

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...

  2. 【LeetCode题意分析&解答】37. Sudoku Solver

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  3. 【LeetCode题意分析&解答】35. Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  4. ACM金牌选手整理的【LeetCode刷题顺序】

    算法和数据结构知识点图 首先,了解算法和数据结构有哪些知识点,在后面的学习中有 大局观,对学习和刷题十分有帮助. 下面是我花了一天时间花的算法和数据结构的知识结构,大家可以看看. 后面是为大家 精心挑 ...

  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(4数之和)

    Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums s ...

  7. 【LeetCode算法题库】Day7:Remove Nth Node From End of List & Valid Parentheses & Merge Two Lists

    [Q19] Given a linked list, remove the n-th node from the end of list and return its head. Example: G ...

  8. 【LeetCode算法题库】Day4:Regular Expression Matching & Container With Most Water & Integer to Roman

    [Q10] Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  9. 【LeetCode算法题库】Day3:Reverse Integer & String to Integer (atoi) & Palindrome Number

    [Q7]  把数倒过来 Given a 32-bit signed integer, reverse digits of an integer. Example 1: Input: 123 Outpu ...

  10. 【LeetCode算法题库】Day1:TwoSums & Add Two Numbers & Longest Substring Without Repeating Characters

    [Q1] Given an array of integers, return indices of the two numbers such that they add up to a specif ...

随机推荐

  1. JDK,JRE,JVM的基础理解

    1.JVM -- java virtual machine JVM就是我们常说的java虚拟机,它是整个java实现跨平台的 最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类 ...

  2. MongoDB实战开发

    [目标]:本文将以实战的形式,向您展示如何用C#访问MongoDB,完成常见的数据库操作任务, 同时,也将介绍MongoDB的客户端(命令行工作模式)以及一些基础的命令. [说明]:MongoDB是什 ...

  3. MySQL 的更新操作update

    1 更新操作(单表更新) 1)单表更新 update [low_priority] [ignore] table_reference set col_name1={expr1|default},col ...

  4. selenium IDE 命令二(断言、验证、等待、变量)

    测试用例需要做断言和验证,在seleniumIDE中提供了断言和验证来对结果进行比较 首先通过打开seleniumIDE,在页面任意一个元素右键,选择最后一个选项“show all available ...

  5. JDBC(1)-连接数据库

    主要步骤包括: 加载驱动: 连接数据库: 使用语句操作数据库: 关闭数据库连接,释放资源. 1.需要导包: 2.加载数据驱动: mysql驱动名:com.mysql.jdbc.Driver 加载方式: ...

  6. Helper Devise: could not find the `Warden::Proxy` instance on request environment

    在使用devise这个gem时,编写控制器层的单元测试,你需要在你的rspec帮助文件 rails_helper.rb里添加下面这一样 RSpec.configure do |config| conf ...

  7. 在W3C SCHOOL网站上发现一个关于Schema的错误

    原地址是http://www.w3school.com.cn/schema/schema_complex_empty.asp 下面这个例子是不正确的 xmlspy报错. 因为<xs:restri ...

  8. Unity5.x在mac下的破解

    工具下载 http://www.ceeger.com/forum/read.php?tid=23396&uid=24111 破解unity5.x版本亲测有效 但是他的说明不详细 下载后,里面有 ...

  9. Notepad++如何删除空行和空白字符

    Notepad++如何删除空行和空白字符 1.Notepad++编辑器在编辑选项里面包括很多功能,编辑->行操作->移除空行(包括空白字符). 2.Notepad++查找替换支持正则替换. ...

  10. java并发编程(3)避免活跃性危险

    活跃性危险 一.死锁 发生:每个人都不愿意放弃自己的锁,确想要别人的锁,这就会导致死锁  1.锁顺序死锁:如果每个线程以固定的顺序获取锁,那么至少在程序中不会出现锁顺序导致的死锁: 因为顺序固定如:所 ...