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数和的更多相关文章

  1. LeetCode 三数之和 — 优化解法

    LeetCode 三数之和 - 改进解法 题目:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复 ...

  2. 【数据结构】Hash表简介及leetcode两数之和python实现

    文章目录 Hash表简介 基本思想 建立步骤 问题 Hash表实现 Hash函数构造 冲突处理方法 leetcode两数之和python实现 题目描述 基于Hash思想的实现 Hash表简介 基本思想 ...

  3. Leetcode 1577 数的平方等于两数乘积的方法数

    Leetcode 1577 数的平方等于两数乘积的方法数 题目 给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1:三元组 ( ...

  4. [LeetCode]丑数 II&C++中priority_queue和unordered_set的使用

    [LeetCode]丑数 II&C++中priority_queue和unordered_set的使用 考虑到现实因素,LeetCode每日一题不再每天都写题解了(甚至有可能掉题目?--)但对 ...

  5. LeetCode两数之和

    LeetCode 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...

  6. python LeetCode 两数相除

    近一个月一直在写业务,空闲时间刷刷leetcode,刷题过程中遇到了一道比较有意思的题目,和大家分享. 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使 ...

  7. [LintCode/LeetCode]——两数和、三数和、四数和

    LintCode有大部分题目来自LeetCode,但LeetCode比较卡,下面以LintCode为平台,简单介绍我AC的几个题目,并由此引出一些算法基础. 1)两数之和(two-sum) 题目编号: ...

  8. LeetCode.1175-质数排列(Prime Arrangements)

    这是小川的第413次更新,第446篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第264题(顺位题号是1175).返回1到n的排列数,以使质数处于质数索引(索引从1开始).(请 ...

  9. LeetCode.1025-除数游戏(Divisor Game)

    这是小川的第382次更新,第411篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第244题(顺位题号是1025).Alice和Bob轮流玩游戏,Alice首先出发. 最初 ...

  10. LeetCode.12-整数转罗马数字符串(Integer to Roman)

    这是悦乐书的第351次更新,第376篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第6题(顺位题号是12).罗马数字由七个不同的符号表示:I,V,X,L,C,D和M. ...

随机推荐

  1. C#题目及答案(2)

    1. NET和C#有什么区别 答:.NET一般指 .NET FrameWork框架,它是一种平台,一种技术. C#是一种编程语言,可以基于.NET平台的应用. 2.一列数的规则如下: 1.1.2.3. ...

  2. JavaScript运行机制详解

    JavaScript运行机制详解   var test = function(){ alert("test"); } var test2 = function(){ alert(& ...

  3. git服务器搭建全程

    为了后续安装能正常进行,我们先来安装一些相关依赖库和编译工具 [root@VM_95_113_centos ~]# yum install curl-devel expat-devel gettext ...

  4. Echarts 修改字体样色 X、Y轴

    1.雷达图修改字体颜色 polar: [ { name:{ show: true, formatter: null, textStyle: { //设置颜色 color: '#109cad' } }, ...

  5. HttpUrlConnection底层实现和关于java host绑定ip即时生效的设置及分析

    最近有个需求需要对于获取URL页面进行host绑定并且立即生效,在java里面实现可以用代理服务器来实现:因为在测试环境下可能需要通过绑定来访问测试环境的应用实现代码如下: public static ...

  6. 面试题中关于String的常见操作

    题目1: 将用户输入的一段话,每个单词的首字母大写, 每个单词之间的空格调整为只有一个,遇到数字,将数字与后一个单词用下划线 "_" 进行连接 题目2:将 i @@ am @@@ ...

  7. idea输出目录详解

    引言:在项目中遇到了一个问题,在使用idea时,项目中Tomcat的虚拟目录映射总是失败,而当我采用myeclipse时却能映射过去. 自己花费了很长时间,终于找出了问题所在,原来是由于idea自己采 ...

  8. 力扣(LeetCode)219. 存在重复元素 II

    给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k. 示例 1: 输入: nums = ...

  9. 修改记录-优化后(springboot+shiro+session+redis+ngnix共享)

    1.普通用户实现redis共享session 1.配置 #cache指定缓存类型 spring.cache.type=REDIS #data-redis spring.redis.database=1 ...

  10. python paramiko 模块简单介绍

    背景,公司的很多服务包括数据库访问都需要通过跳板机访问,为日常工作及使用带来了麻烦,特别数python直接操作数据更是麻烦了,所以一直想实现python 通过跳板机访问数据库的操作. 首先了解到了 p ...