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. python爬虫训练——爬poj题目

    首先要解决的就是不同的题目在不同的页上,也就是要实现翻页功能,自动获取所要爬取的地址,通过分析可以得出不同的页面也就是volume=后面的数字不同 所以我们可以用re模块来替换即可: new_url ...

  2. Nginx教程---01.Nginx入门

    create by 三七二十一 LZ参考视频(年代久远,但万变不离其宗): 链接:https://pan.baidu.com/s/1O_MmN0c3ckM6vbk08n8Qkg 密码:z9zr 01_ ...

  3. 项目Alpha冲刺——代码规范、冲刺任务与计划

    作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Alpha冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合评估及可视化分析平台 这个作业的 ...

  4. P1622 释放囚犯

    传送门 区间DP简介: 在写这题前,需要先弄清楚区间DP是如何操作的: 区间DP的做法还是相对固定的,没有其他类型DP的复杂多变.主要思想就是先在小区间进行DP得到最优解,然后再利用小区间的最优解合并 ...

  5. [原][粒子特效][spark]插值器interpolator

    深入浅出spark粒子特效连接:https://www.cnblogs.com/lyggqm/p/9956344.html 插值器是体现粒子生命周期变化的功能 group使用到插值器的方式: 可以看到 ...

  6. LaTeX 交叉引用系统简介

    目录 摘要 1. 简介 2. 指定标签或标记符 3. 标签的位置 4. 引用的生成和更新 5. 引用相关的警告信息 6. 扩展引用功能的宏包 6.1 varioref宏包 6.2 cleveref宏包 ...

  7. Spring @Configuration 和 @Bean 注解

    @Configuration 和 @Bean 注解 带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源.@Bean 注解告诉 Spri ...

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

    给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3,1] 输出: true ...

  9. SpringMVC 处理Date类型数据@InitBinder @DateTimeFormat 注解 的使用

    使用SpringMVC的时候,需要将表单中的日期字符串转换成对应JavaBean的Date类型,而SpringMVC默认不支持这个格式的转换,解决方法有两种,如下: 方法一 . 在需要日期转换的Con ...

  10. 虚拟机ubuntu的常用命令集合

    一.文件/文件管理 ls 列出当前目录文件(不包括隐含文件) ls -a 列出当前目录文件(包括隐含文件) ls -l 列出当前目录下文件的详细信息 cd .. 回当前目录的上一级目录 cd -回上一 ...