【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和
【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和
LeetCode454. 四数相加II
题目链接:454. 四数相加II
初次尝试
没有思路,对于map的使用还不是非常熟练,正好借这几个题多练习一下。
看完代码随想录后的想法
四个数组两两一组,写成两个嵌套的for循环,这样可以保证时间复杂度最小,其中使用map的原因是不仅要统计前两个数组的元素和,还要统计每个和出现的次数。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> hashMap;
int count = 0;
for (int i = 0; i < nums1.size(); i++) {
for (int j = 0; j < nums2.size(); j++) {
auto iter = hashMap.find(nums1[i] + nums2[j]);
if (iter != hashMap.end()) {
iter -> second++;
}
else {
hashMap.insert(pair<int, int>(nums1[i] + nums2[j], 1));
}
}
}
for (int i = 0; i < nums3.size(); i++) {
for (int j = 0; j < nums4.size(); j++) {
auto iter = hashMap.find(0 - nums3[i] - nums4[j]);
if (iter != hashMap.end()) {
count += iter -> second;
}
}
}
return count;
}
};
LeetCode383. 赎金信
题目链接:383. 赎金信
初次尝试
感觉和242. 有效的字母异位词是一个思路的题,解起来不难,一遍ac。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
vector<int> hashVec(26, 0);
for (int i = 0; i < magazine.size(); i++) {
hashVec[magazine[i] - 'a']++;
}
for (int i = 0; i < ransomNote.size(); i++) {
hashVec[ransomNote[i] - 'a']--;
if (hashVec[ransomNote[i] - 'a'] < 0) {
return false;
}
}
return true;
}
};
看完代码随想录后的想法
思路一样。
LeetCode15. 三数之和
题目链接:15. 三数之和
初次尝试
思路比较混乱,没有想到解法。
看完代码随想录后的想法
这题应该是刷题刷到现在,思考量最大的一道题了,很容易想着想着陷入疑惑,最好边画图边想。这里按照思考顺序列举几个解题的关键点:
为什么上来要先排序?LeetCode官方题解中对此有非常清楚的解释。
「不重复」的本质是什么?我们保持三重循环的大框架不变,只需要保证:
第二重循环枚举到的元素不小于当前第一重循环枚举到的元素;
第三重循环枚举到的元素不小于当前第二重循环枚举到的元素。
也就是说,我们枚举的三元组 (a, b, c) 满足a≤b≤c,保证了只有 (a, b, c)这个顺序会被枚举到,而 (b, a, c)、(c, b, a) 等等这些不会,这样就减少了重复。要实现这一点,我们可以将数组中的元素从小到大进行排序,随后使用普通的三重循环就可以满足上面的要求。
但是仅仅排序之后就可以保证输出的三元组不重复了吗?不一定,排序过后的数组仍然可能存在连续相等的元素,这可能会导致在遍历过程中,连续几个循环a取得相同的值,导致输出重复的三元组,b和c同理,所以仍然需要对abc去重。
但是对于a和bc的去重方式又有所差别,对于b和c,我们可以在left和right指针指向的下一个元素和现在指向的元素相等的时候,直接跳过下一个元素;而对于a,我们需要考虑特殊的情况,比如遇到
{0, 0, 0}或者{-1, -1, 2}这样的输入时,如果使用nums[i] == nums[i + 1]这样的判断,就会漏掉(0, 0, 0)或者(-1, -1, 2)这样的三元组,所以对于a,应该使用nums[i] == nums[i - 1]这样的判断,这样才能保证既不漏掉特殊情况,又不输出因为a重复而重复的三元组。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > 0) {
return ans;
}
// 对a去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1, right = nums.size() - 1;
while (left < right) {
if (nums[i] + nums[left] + nums[right] < 0) {
left++;
}
else if (nums[i] + nums[left] + nums[right] > 0) {
right--;
}
else {
ans.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 对b和c去重
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return ans;
}
};
LeetCode18. 四数之和
题目链接:18. 四数之和
初次尝试
算是三数之和的拓展题,本质上就是在三数之和的基础上再加一层for循环,但是在实际写的过程中有几个细节需要注意。
看完代码随想录后的想法
两点细节需要注意:
- 剪枝处理的判断条件和三数之和不同,内外两层剪枝处理的返回语句不同。
- 需要在四数求和的时候将int强制转型为long int,防止溢出。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
// 剪枝处理
if (nums[i] > target && nums[i] >= 0) {
return ans;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < nums.size(); j++) {
// 2级剪枝处理
if (nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) {
break;
}
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
int left = j + 1, right = nums.size() - 1;
while (left < right) {
// 强制转型
if ((long) nums[i] + nums[j] + nums[left] + nums[right] < target) {
left++;
}
else if ((long) nums[i] + nums[j] + nums[left] + nums[right] > target) {
right--;
}
else {
ans.push_back(vector<int>{nums[i], nums[j], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
}
return ans;
}
};
【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和的更多相关文章
- 【哈希表】leetcode454——四数相加II
编号454:四数相加II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为 ...
- Leetcode 454.四数相加II
四数相加II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单 ...
- Java实现 LeetCode 454 四数相加 II
454. 四数相加 II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为 ...
- 代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和
第一题454.四数相加II 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, ...
- LeetCode 445. 两数相加 II(Add Two Numbers II)
445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...
- Java实现 LeetCode 445 两数相加 II
445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ...
- LeetCode454. 四数相加 II
题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...
- [Swift]LeetCode445. 两数相加 II | Add Two Numbers II
You are given two non-empty linked lists representing two non-negative integers. The most significan ...
- LeetCode 445——两数相加 II
1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...
随机推荐
- SpringBoot的创建和特性
一.SpringBoot的特点 创建独立的Spring应用程序 直接嵌入Tomcat.Jetty或Undertow(无需部署WAR文件) 提供自以为是的"starter"依赖项,以 ...
- 微服务性能分析|Pyroscope 在 Rainbond 上的实践分享
随着微服务体系在生产环境落地,也会伴随着一些问题出现,比如流量过大造成某个微服务应用程序的性能瓶颈.CPU利用率高.或内存泄漏等问题.要找到问题的根本原因,我们通常都会通过日志.进程再结合代码去判断根 ...
- 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 官方扩展集锦(Microsoft.Extensions on Nuget)
什么是Microsoft.Extensions .NET Platform Extensions是一套.Net官方的API集合,提供了一些常用的编程模式和实用工具,例如依赖项注入.日志记录.缓存.Ho ...
- Java核心知识体系4:AOP原理和切面应用
1 概述 我们所说的Aop(即面向切面编程),即面向接口,也面向方法,在基于IOC的基础上实现. Aop最大的特点是对指定的方法进行拦截并增强,这种增强的方式不需要业务代码进行调整,无需侵入到业务代码 ...
- ASP.NET CORE在docker中的健康检查(healthcheck)
在使用docker-compose的过程中,很多程序都提供了健康检查(healthcheck)的方法,通过健康检查,应用程序能够在确保其依赖的程序都已经启动的前提下启动,减少各种错误的发生,同时,合理 ...
- Java SE 16 新增特性
Java SE 16 新增特性 作者:Grey 原文地址:Java SE 16 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- DIN 66025标准下G Code基础代码释义
基础/前提 XYZ指示常规的三个轴号,PQUVW为可以增加的五个轴,ABC为可以增加的旋转轴 实例 G0 快速定位(点位运动) G1 直线运动(插补) G2 顺时针圆弧运动(插补) G3 逆时针圆弧运 ...
- ViewGroup事件分发源码分析
1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...
- ar9485 win10 笔记本电脑 无线网间歇性掉线
问题 新安装了系统,刚开始上网正常,下载东西或者待机一段时间后掉线了. wifi都能搜到,就是连不上,重启电脑可以解决,但是每次重启很麻烦,必须找到治本的方法. 排除问题 1.手机连接没有问题,排除 ...
- PLSQL 与 PLPGSQL
KingbaseES 为了更好地适应用户的oracle 应用,实现了对 plsql 的支持,用户可以根据需要使用 plsql 或 plpgsql. 以下简要介绍下二者的差异 一.格式差异 1.plpg ...