【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. ...
随机推荐
- 转csdn某位同学的 感谢bmfont
UGUI 使用BMFont 首先要知道 Custom Font 的原理,不知道的同学可以先看这篇[Custom Font 原理](http://blog.csdn.net/liqiangeastsun ...
- IDEA 的Class not found: "..."Empty test suite
Junit测试的时候出现 IDEA 的Class not found: "..."Empty test suite问题. 尝试一下解决方法: 第一种方法: 1.modules&g ...
- 前端html5/css基础知识
https://www.cnblogs.com/clschao/articles/10073124.html
- base64 加密原理 解密原理
假设需要加密的字符串是Jasmine 具体转换步骤: 第一步 将待转换的字符串转为一个个字符第二步 计算每一个字符对应的ASCII码十进制第三步 计算出十进制对应的二进制,若不足8位,在前面添加0进行 ...
- 你真的了解restful api吗?
前言 在以前,一个网站的完成总是“all in one”,页面,数据,渲染全部在服务端完成,这样做的最大的弊端是后期维护,扩展极其痛苦,开发人员必须同时具备前后端知识.于是慢慢的后来兴起了前后端分离的 ...
- x1c 6th usb-c 接口灯常亮,电源无法充电
症状: 左侧能充电的那个usb-c 红灯始终常亮.拔下电源线也亮着. 系统里电源是始终显示正在充电,即使拔掉外接电源也显示连着外接电源正在充电! ——最吓人的是,用U盘启动进PE,想重装win10,结 ...
- 牛客OI周赛4-提高组 A K小生成树(kmst)
K小生成树(kmst) 思路: 暴力+并查集 枚举边的子集,用并查集判断两个点联不联通 代码: #include<bits/stdc++.h> using namespace std; # ...
- [MySQL]典型的行列转换
列变成行 测试数据库数据样式: 应用的sql语句: SELECT TM,NAME,SUM(GE) AS 'GE',SUM(GD) AS 'GD',SUM(CT) AS 'CT',SUM(NUM) AS ...
- Getting started with Processing 第六章总结
平移,旋转和缩放 前言 在这一章节中,平移.旋转和缩放都是以原点为基准的.并且是通过控制坐标系原点的位置来达到图元平移,旋转.缩放的视觉效果.作者在文中的原话是:另一种在屏幕上改变位置和移动物体的技术 ...
- 雷林鹏分享:jQuery EasyUI 窗口 - 创建简单窗口
jQuery EasyUI 窗口 - 创建简单窗口 创建一个窗口(window)非常简单,我们创建一个 DIV 标记: Some Content. 现在运行测试页面,您会看见一个窗口(window)显 ...