【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. ...
随机推荐
- Mac环境下扩容 .vmdk 镜像容量
参考: Resizing a VirtualBox Disk Image (.vmdk) on a Mac Mac环境下扩容 .vmdk 镜像容量 在安装虚拟机时,原有的vmdk镜像容量只有20G,在 ...
- HDU 5844 LCM Walk(数学逆推)
http://acm.hdu.edu.cn/showproblem.php?pid=5584 题意: 现在有坐标(x,y),设它们的最小公倍数为k,接下来可以移动到(x+k,y)或者(x,y+k).现 ...
- rostopic demo
发布者 #!/usr/bin/env python2. # -*- coding: utf- -*- import rospy from hdw_driver.msg import update_fi ...
- Spotlight 监控Linux服务器的性能
Spotlight功能:详细的进程跟踪功能远程连接在线的Unix/Linux的调优指南事件日志跟踪配置警报 详细的进程跟踪功能:Spotlight对具体的Unix / Linux的进程长达24小时的历 ...
- FILE,id不一致
当图片全部是新增的时候,id和FILE一一对应,后台可以匹配处理. array(1) { ["banner_img"] => array(5) { ["name&q ...
- SPOJ 刷题记录
按点赞数降序 297 二分 #include<bits/stdc++.h> using namespace std; #define fi first #define se second ...
- 第 4 章 容器 - 029 - 限制容器的 Block IO
限制容器的 Block IO Block IO 是另一种可以限制容器使用的资源. Block IO 指的是磁盘的读写,docker 可通过设置权重.限制 bps 和 iops 的方式控制容器读写磁盘的 ...
- Pytorch Visdom可视化工具
2018-12-04 14:05:49 Visdom是Facebook专门为PyTorch开发的一款可视化工具,其开源于2017年3月.Visdom十分轻量级,但却支持非常丰富的功能,能胜任大多数的科 ...
- 两排序数组的中位数 Median of Two Sorted Arrays
2018-11-18 23:33:28 问题描述: 问题求解: 这个问题是一个比较有难度的可以使用二分搜索法求解的问题,如果采用朴素的解法进行merge再找中位数的话,其时间复杂度为O(n1 + n2 ...
- HAL无阻塞延时
//实现间隔time_interval时间点亮红灯(此时间间隔并不是绝对的,是大于等于的关系)//用于系统要求无延时且延时时间粗略的场合,比如间隔一段时间采样数据,间隔一段时间点亮状态灯等//HAL_ ...