【LeetCode】N数和
1. 3Sum
给定一个无序数组(可能存在重复元素),是否存在三个数之和为0,输出所有不重复的三元组。
e.g. 给定数组 [-1, 0, 1, 2, -1, -4],
结果集为:
[
[-1, 0, 1],
[-1, -1, 2]
]
原理:
首先升序排序
----------------------------------------------------
^ ^ ^
| | |
| j k
i
j 往后扫,k 往前扫
三数和 < 0 就 j++,> 0 就 k--
直到 == 0 再取下一组
C++实现:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size(); i++) {
// 控制i不重复,只指向一组重复数字的第一个
if (i > && nums[i] == nums[i-])
continue;
int j = i + , k = nums.size() - ;
while (j < k) {
if (nums[i] + nums[j] + nums[k] < ) {
j++;
} else if (nums[i] + nums[j] + nums[k] > ) {
k--;
} else {
result.push_back({nums[i], nums[j], nums[k]});
// 控制j不重复,只指向一组重复数字的第一个
while (j < k && nums[j] == nums[j+])
j++;
// 控制k不重复,只指向一组重复数字的最后一个
while (j < k && nums[k] == nums[k-])
k--;
j++;
k--;
}
}
}
return result;
}
第4行如果写 i < nums.size() - 2会报 Runtime Error 错,不知道为什么?
2. 3Sum Closest
给定一个无序数组(可能存在重复元素),是否存在三个数之和最接近给定数target,输出这三个数的和。(假设每条输入只有唯一答案)
e.g. 给定数组 [-1, 2, 1, -4],target = 1
则最接近target的和为2 (-1 + 2 + 1 = 2)
C++实现:
int threeSumClosest(vector<int>& nums, int target) {
// 数组元素小于等于3个则直接返回数组和
if (nums.size() <= ) {
return accumulate(nums.begin(), nums.end(), );
}
int close = nums[] + nums[] + nums[];
sort(nums.begin(), nums.end());
for (int i = ; i < nums.size(); i++) {
if (i > && nums[i] == nums[i-])
continue;
int j = i + , k = nums.size() - ;
while (j < k) {
int current = nums[i] + nums[j] + nums[k];
if (abs(current - target) < abs(close - target)) {
close = current;
if (current == target) {
return current;
}
}
(current < target) ? j++ : k--;
}
}
return close;
}
PS:
C++对应的Java代码
vector<vector<int>> List<List<Integer>>
sort(nums.begin(), nums.end()); Arrays.sort(nums);
result.push_back({nums[i], nums[j], nums[k]}); result.add(Arrays.asList(nums[i], nums[j], nums[k]));
abs(n) Math.abs(n)
3. 4Sum
给定一个无序数组(可能存在重复元素),是否存在四个数之和为目标数target,输出所有不重复的四元组。
e.g. 给定数组[1, 0, -1, 0, -2, 2],target = 0.
结果集为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
原理与 3 Sum 相似,首先升序排序,i 从第一个扫到最后,j 从 i + 1 扫到最后。
两个指针为 p 和 k ,p 往后扫,k 往前扫,四数和 < 0 就 p++,> 0 就 k--;直到 == 0 再取下一组 p 和 k。
C++实现:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
if (n < ) return {};
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for (int i = ; i < n - ; i++) {
if (i > && nums[i] == nums[i - ]) continue;
// 提高效率,本轮能取的最小的和与本轮能取的最大的和
if (nums[i] + nums[i + ] + nums[i + ] + nums[i + ] > target) break;
if (nums[i] + nums[n - ] + nums[n - ] + nums[n - ] < target) continue;
for (int j = i + ; j < n - ; j++) {
if (j > i + && nums[j] == nums[j - ]) continue;
// 提高效率,本轮能取的最小的和与本轮能取的最大的和
if (nums[i] + nums[j] + nums[j + ] + nums[j + ] > target) break;
if (nums[i] + nums[j] + nums[n - ] + nums[n - ] < target) continue;
// 最后两个指针p和k在最内层while上面定义
// 如模仿三数和在上面定义k并在j循环体内控制条件写j < k会导致j扫不到最后
int p = j + , k = n - ;
while (p < k) {
if (nums[i] + nums[j] + nums[p] + nums[k] < target) p++;
else if (nums[i] + nums[j] + nums[p] + nums[k] > target) k--;
else {
result.push_back({nums[i], nums[j], nums[p], nums[k]});
while (p < k && nums[p] == nums[p + ]) p++;
while (p < k && nums[k] == nums[k - ]) k--;
p++;
k--;
}
}
}
}
return result;
}
【LeetCode】N数和的更多相关文章
- LeetCode 三数之和 — 优化解法
LeetCode 三数之和 - 改进解法 题目:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复 ...
- 【数据结构】Hash表简介及leetcode两数之和python实现
文章目录 Hash表简介 基本思想 建立步骤 问题 Hash表实现 Hash函数构造 冲突处理方法 leetcode两数之和python实现 题目描述 基于Hash思想的实现 Hash表简介 基本思想 ...
- Leetcode 1577 数的平方等于两数乘积的方法数
Leetcode 1577 数的平方等于两数乘积的方法数 题目 给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1:三元组 ( ...
- [LeetCode]丑数 II&C++中priority_queue和unordered_set的使用
[LeetCode]丑数 II&C++中priority_queue和unordered_set的使用 考虑到现实因素,LeetCode每日一题不再每天都写题解了(甚至有可能掉题目?--)但对 ...
- LeetCode两数之和
LeetCode 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...
- python LeetCode 两数相除
近一个月一直在写业务,空闲时间刷刷leetcode,刷题过程中遇到了一道比较有意思的题目,和大家分享. 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使 ...
- [LintCode/LeetCode]——两数和、三数和、四数和
LintCode有大部分题目来自LeetCode,但LeetCode比较卡,下面以LintCode为平台,简单介绍我AC的几个题目,并由此引出一些算法基础. 1)两数之和(two-sum) 题目编号: ...
- LeetCode.1175-质数排列(Prime Arrangements)
这是小川的第413次更新,第446篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第264题(顺位题号是1175).返回1到n的排列数,以使质数处于质数索引(索引从1开始).(请 ...
- LeetCode.1025-除数游戏(Divisor Game)
这是小川的第382次更新,第411篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第244题(顺位题号是1025).Alice和Bob轮流玩游戏,Alice首先出发. 最初 ...
- LeetCode.12-整数转罗马数字符串(Integer to Roman)
这是悦乐书的第351次更新,第376篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第6题(顺位题号是12).罗马数字由七个不同的符号表示:I,V,X,L,C,D和M. ...
随机推荐
- HDU 5791 Two(LCS求公共子序列个数)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5791 题意: 给出两个序列,求这两个序列的公共子序列的总个数. 思路: 和LCS差不多,dp[i][ ...
- vue--vuex
https://vuex.vuejs.org/ vuex是专为 vue.js 应用程序开发的 状态管理模式 采用集中式存储管理应用的所有组件状态 并以相应的规则保证状态以一种可预测的方式发生变化 vu ...
- _itemmod_exchange_item
物品强化说明 表说明 `item`物品ID `exchangedItem` 升级后的物品ID `upFlag` 物品等级模式0或1,一般为0 `reqId` 需求ID `chance` 升级几率 `c ...
- Sqlserver中分页,2012后支持offset + fetch,2012之前用rownum嵌套查询
今天发现原先用的sql offset fetch好用,换了一个DB就歇菜 歇菜截图 比较了一下,是数据库版本的问题 一个是13,一个是10 版本低的不支持用offset + fetch 进行分页,ms ...
- django模型表单ModelForm
如果你正在构建一个数据库驱动的应用,那么你可能会有与Django的模型紧密映射的表单.比如,你有个BlogComment模型,并且你还想创建一个表单让大家提交评论到这个模型中.在这种情况下,写一个fo ...
- PyMongo官方文档翻译——VNPY
PyMongo是MongoDB数据库的python模块 VNPY默认的数据库,没有采用SQL类型的数据库,而是采用No-Sql类型的MongoDB数据库, 对于想了解VNPY内部结构的童鞋,多多少少会 ...
- linux yum+wget详解
在做自动化测试的时候,有个test需要执行命令:wget http://www.aliyun.com,但是返回的结果是未找到命令wget,于是百度了相关资料,发现没有安装wget,于是利用yum in ...
- 如何调节tomcat初始内存
1.linux下调节tomcat初始内存大小 linux下tomcat的运行文件为catalina.sh,打开文件,在文件靠近顶部找到“ JAVA_OPTS ”字样,在它后面添加如下内容即可 # JA ...
- [JSP] Action Tags
1.: forward转发请求to another resource (可能是jsp, html,等). 语法: <jsp:forward page="relativeURL | &l ...
- centos7:mysql-5.7.23安装(二进制安装)
mysql有二进制码安装,和源码编译安装(mysql5.5使用cmake安装,mysql5.7需要安装boost依赖安装),因为boost依赖安装麻烦,所以用二进制码安装 MySql 5.7.23安装 ...