博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] 4Sum 四数之和
阅读量:6800 次
发布时间:2019-06-26

本文共 2816 字,大约阅读时间需要 9 分钟。

 

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, abcd)
  • 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中关于数字之和还有其他几道,分别是  , , ,虽然难度在递增,但是整体的套路都是一样的,在这里为了避免重复项,我们使用了STL中的set,其特点是不能有重复,如果新加入的数在set中原本就存在的话,插入操作就会失败,这样能很好的避免的重复项的存在。此题的O(n^3)解法的思路跟  基本没啥区别,就是多加了一层for循环,其他的都一样,代码如下:

 

解法一:

class Solution {public:    vector
> fourSum(vector
&nums, int target) { set
> res; sort(nums.begin(), nums.end()); for (int i = 0; i < int(nums.size() - 3); ++i) { for (int j = i + 1; j < int(nums.size() - 2); ++j) { if (j > i + 1 && nums[j] == nums[j - 1]) continue; int left = j + 1, right = nums.size() - 1; while (left < right) { int sum = nums[i] + nums[j] + nums[left] + nums[right]; if (sum == target) { vector
out{nums[i], nums[j], nums[left], nums[right]}; res.insert(out); ++left; --right; } else if (sum < target) ++left; else --right; } } } return vector
>(res.begin(), res.end()); }};

 

但是毕竟用set来进行去重复的处理还是有些取巧,可能在Java中就不能这么做,那么我们还是来看一种比较正统的做法吧,手动进行去重复处理。主要可以进行的有三个地方,首先在两个for循环下可以各放一个,因为一旦当前的数字跟上面处理过的数字相同了,那么找下来肯定还是重复的。之后就是当sum等于target的时候了,我们在将四个数字加入结果res之后,left和right都需要去重复处理,分别像各自的方面遍历即可,参见代码如下:

 

解法二:

class Solution {public:    vector
> fourSum(vector
&nums, int target) { vector
> res; int n = nums.size(); sort(nums.begin(), nums.end()); for (int i = 0; i < n - 3; ++i) { if (i > 0 && nums[i] == nums[i - 1]) continue; for (int j = i + 1; j < n - 2; ++j) { if (j > i + 1 && nums[j] == nums[j - 1]) continue; int left = j + 1, right = n - 1; while (left < right) { int sum = nums[i] + nums[j] + nums[left] + nums[right]; if (sum == target) { vector
out{nums[i], nums[j], nums[left], nums[right]}; res.push_back(out); while (left < right && nums[left] == nums[left + 1]) ++left; while (left < right && nums[right] == nums[right - 1]) --right; ++left; --right; } else if (sum < target) ++left; else --right; } } } return res; }};

 

类似题目:

 

参考资料:

 

转载地址:http://nnuwl.baihongyu.com/

你可能感兴趣的文章
Cocos2d-X中的ZORDER和Tag
查看>>
【git】git pull
查看>>
Java NIO(一)I/O模型概述
查看>>
【转】对博士学位说永别
查看>>
SQL Server等待事件—RESOURCE_SEMAPHORE_QUERY_COMPILE
查看>>
windowns 2008(apache2.2.25 x86 openssl0.98y) 升级openssl1.0.1e(为了支持小程序接口TLS1.2)
查看>>
在.NET下如何预防XXE注入攻击
查看>>
HTC T8878刷机手册
查看>>
修改Discuz! X2文章标题字数限制
查看>>
glloader移植到了Android
查看>>
【转载】dotnet 线程同步
查看>>
static_cast与dynamic_cast转换
查看>>
libevent2的hello world程序 —— 字符大写服务器
查看>>
LINQ简记(2):重要概念
查看>>
jQuery 1.6 源码学习(二)——core.js[2]之extend&ready方法
查看>>
[WPF疑难] 继承自定义窗口
查看>>
WebRTC网关服务器单端口方案实现
查看>>
018 easygui的使用
查看>>
iphone 开发h5 踩过的坑
查看>>
微信支付demo集
查看>>