代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

第2章: MMU Notifier 全局通知器的核心原理⭐ 摘要 MMU Notifier机制是Linux内核中用于处理内存地址空间变化通知的关键框架。其设计遵循解耦与标准化、最小侵入性、高性能和安全性四大原则,采用三层架构实现上层应用、核心层与内存管理层的协作。框架提供两种通知模型:全局订阅的mmu_notifier和区间订阅的mmu_interval_notifier,分别适用于KVM虚拟化和GPU共享虚拟内存等不同场景。核心数据结构mmu_notifier_ops定义了设备驱动需要实现的回调函数集合,包括进程退出处理、页面老化管理、地址范围失效通知等功能。 阅读详情

454.四数相加II

力扣454

这道题比“四数之和”简单的一个地方在于,从四元组中找到的组合不需要去重,找到多少个算多少个。

如果四个元组分别为ABCD,整体思路是,把AB遍历完,将a+b的值放到一个集合里,然后再遍历CD时,去判断集合中有没有我们需要的-(c+d)使得四数之和为0。因此确定本题采用哈希法。

本题数组下标来做映射的话,占用存储空间太大,所以排除数组。又因为需要统计符合条件的组合的个数,所以,此处采用map中的unordered_map

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> mymap;
        int count = 0;
        for(int a:nums1){
            for(int b:nums2){
                mymap[a+b]++;
            }
        }
        for(int c:nums3){
            for(int d:nums4){
                int t = -(c+d);
                if(mymap.find(t)!=mymap.end()){
                    count+=mymap[t];
                }
            }
        }
        return count;
    }
};

有一个要注意的是,在找到符合条件的abcd后不是用count++计数,而是count+=mymap[-(c+d)],因为找到一个-(c+d)对应的a+b的组合有几个就应该计几个。

383. 赎金信

力扣383

本题判断 ransomNote 能不能由 magazine 里面的字符构成。magazine 中的每个字符只能在 ransomNote 中使用一次。这道题其实和有效的字母异位词非常相似,只需要稍稍改动一下:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int hash[26];
        for(int i=0;i<26;i++){
            hash[i]=0;
        }
        for(int i=0;i<magazine.size();i++){
            hash[magazine[i]-'a']++;
        }
        for(int i=0;i<ransomNote.size();i++){
            hash[ransomNote[i]-'a']--;
        }
        for(int i=0;i<26;i++){
            if(hash[i]<0) return false;
        }
        return true;
    }
};

将最后一个for循环的判断if条件改为hash【i】<0即可,即,判断ransomNote使用magazine中的字母后有没有多用超额。

简化代码:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int hash[26]={};
        for(int i=0;i<magazine.size();i++){
            hash[magazine[i]-'a']++;
        }
        for(int i=0;i<ransomNote.size();i++){
            hash[ransomNote[i]-'a']--;
            if(hash[ransomNote[i]-'a']<0) return false;
        }
        return true;
    }
};

15. 三数之和

力扣15

如果用计算四数相加的方法同样计算三数之和的话,就无法考虑到本题要求的去重操作。

使用哈希法的话,去重的细节非常繁琐。

此处采用代码随想录 中提到多次的双指针法: 

-1-1011
ileftright
abc

要求a+b+c=0 。

大致思路

先让数组从小到大排序。for循环遍历i,指代三数中最小的那个数a。

另外两个数,则用left和right指代,left = i+1,right = 最后一个数。

通过这样的指针分配方式,我们可以知道:

当这三数之和大于0时,需要缩小,right左移;当小于0时,需要增大,left右移。

当正好等于0时,就可以把三个数放入结果集。由nums[i]、nums[left]和nums[right]组成的一维vector添加到result这个二维vector的末尾。(易错点,误写成result.push_back(vector<vector<int>>{nums[i],nums[left],nums[right]});  )

去重细节

1. 剪枝

如果a作为最小的数,已经大于0了,那么无论如何三数之和都不可能等于0了。直接返回result。(注意:a可以等于0,例如0,0,0三数之和)

2. 对a去重

对a进行去重就是使a[i]!=a[i-1]。

为什么是和a[i-1]进行比较呢?

因为如果对a[i] = a[i+1] 就进行跳过的话,会排除掉{-1,-1,2}这种前两个数一致的情况。

注意:if(nums[i]!=nums[i-1]{........}不能这样写去重。因为i = 0时,i-1会造成数组越界,所以要加上i>0的条件:

// 正确去重a方法
if (i > 0 && nums[i] == nums[i - 1]) {
    continue;
}

3. 对b,c去重

while(left<right&&nums[left]==nums[left+1]) left++;//b去重 while(left<right&&nums[right]==nums[right-1]) right--;//c去重

不管b和c怎么挪,while循环里都别忘了加上left<right;

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++){
            if(nums[i]>0) return result;//剪枝
            // 正确去重a方法
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i+1;
            int right = nums.size()-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]>0) right--;
                else if(nums[i]+nums[left]+nums[right]<0) left++;
                else{
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    while(left<right&&nums[left]==nums[left+1]) left++;//b去重
                    while(left<right&&nums[right]==nums[right-1]) right--;//c去重
                    //找到结果两边都需要移动
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
};

ps:以上注意的点都是写完本道题第二天再写时忽略错误的点。 

18. 四数之和 

力扣18

四数之和,和三数之和是一个思路,都是使用双指针法, 只是在三叔之和的基础上再套一层for循环。

如果充分理解了三数之和的算法逻辑,会发现四数之和这道题的步骤简直和“三数之和”一模一样。

a b c d 这四个数,在已有的b c d代码上再套一个遍历a的for循环,在遍历a和b时都是先剪枝再去重。a b c d 对应k i left right

但是由于本题求解的是=target而不是=0,得考虑target<0的情况,不能直接像上题一样通过nums[k]>target来剪枝。想剪枝排除不可能的情况必须同时满足:

if (nums[k] > target && nums[k] >= 0) {
    break; // 这里使用break,统一通过最后的return返回
}

再对b进行二级剪枝时也是如此:

if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
    break;
}

完整代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for(int k=0;k<nums.size();k++){
            if(nums[k]>=0&&nums[k]>target){//第一个数就已经大于target了,不可能符合条件了,直接返回
                break;
            }
            if(k>0&&nums[k]==nums[k-1]) continue;//给a去重
            for(int i=k+1;i<nums.size();i++){
                if(nums[i]+nums[k]>=0&&nums[k]+nums[i]>target) break;
                if(i>k+1&&nums[i]==nums[i-1]) continue;//给b去重
                int left = i+1;
                int right = nums.size()-1;
                while(left<right){
                    if((long)nums[k]+nums[i]+nums[left]+nums[right]>target) right--;
                    else if((long)nums[k]+nums[i]+nums[left]+nums[right]<target) left++;
                    else{
                        result.push_back(vector<int>{nums[k],nums[i],nums[left],nums[right]});
                        while(left<right&&nums[left]==nums[left+1]) left++;//给c去重
                        while(left<right&&nums[right]==nums[right-1]) right--;//给d去重
                        left++;
                        right--;
                    }
                 }
            }
        }
        return result;
    }
};

感想

昨天第一次做这些题时只有第二题是自己做出来的,当时觉得“三数之和”与“四数之和”都很难,第二天再做肯定忘了大部分了。结果没想到,今天做三数之和时几乎都想起来了,只有少数几个细节没有注意到(已经加粗加深理解了)。四数之和昨天没理清的剪枝去重操作今天再做,也可以很顺利地和“三数之和”里的对应上了。

继续加油!

SAP ABAP Web Service 的创建与消费:保姆级教程 SOAP 定义了消息的格式和传输规则,使得 Web Service 可以在不同的操作系统和网络环境中通信。通过 WSDL,服务的提供者可以明确地定义服务的功能,而服务的使用者则可以通过解析 WSDL 文件,了解如何正确地调用该服务。它封装了与 Web 服务通信的所有复杂性,如消息格式的构建、传输协议的选择、请求的发送和响应的处理等。除了本文介绍的 ABAP 编程语言之外,我们还可以通过 Java,Node.js,C++,C#,Python 等其他编程语言来消费本文创建的 ABAP Web Service. 阅读详情

相关推荐

Profinet从站开发初体验:用p-net开源库和树莓派快速搭建一个IO设备模拟器

本文详细介绍了如何使用p-net开源库和树莓派快速搭建Profinet从站IO设备模拟器。从开发环境准备、p-net源码编译到设备模拟器功能实现,提供了全流程实战指南,帮助开发者快速掌握工业通信协议开发技巧,适用于工业自动化领域的设备互联测试与验证。

weixin_30384217的博客 383

代码随想录算法训练营第七天| 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

代码随想录算法训练营第七天| 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

2301_81109252的博客 1038

告别sgmediation!Stata中介效应分析新选择:mediation包完整操作指南

本文介绍了Stata中介效应分析从传统sgmediation命令向mediation包的范式升级。重点阐述了如何使用medeff和medsens命令进行更严谨的因果推断,并执行关键的敏感性分析,以评估结果对未观测混杂的稳健性,为学术研究提供发表级的分析工具。

redis7keeper的博客 1157

代码随想录算法训练营第七天|454.四数相加II 、 383. 赎金信 、 15. 三数之和 、18. 四数之和

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]否则返回 false。给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

wunan233的博客 886

【LAMMPS学习】八、基础知识(4.5)TIP5P水模型

​ 五点 TIP5P 刚性水模型通过添加两个通常无质量的附加位点 L 来扩展three-point TIP3P model,其中放置与氧原子相关的电荷。这些位点 L 位于距氧原子固定距离处,形成从 HOH 平面旋转 90 度的四面角。因此,这些位点在某种程度上近似于氧的孤对,从而改善了水结构,与four-point TIP4P model相比变得更加“四面体”。

荷塘阅色 1421

SAP 基于生产订单行项目外部加工创建采购申请时的一个增强需求

摘要 本文介绍在SAP系统中实现生产订单外协工序自动生成采购申请(PR)时,将指定文本写入PR抬头文本的技术方案。关键点包括: 业务背景:通过CO02事务码将工序标记为外部加工,系统自动生成PR,需在生成时自动写入抬头文本。 技术难点: PR抬头文本存储在STXH/STXL而非EBAN表 标准增强点ME_PROCESS_REQ_CUST在外协场景可能不触发 推荐方案: 使用BAdI ME_REQ_POSTED,在PR过账时点执行 通过Text Object EBANH和Text ID(如B01)写入文本 实

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 622

代码随想录算法训练营第七天 | 454.四数相加II 383.赎金信 15. 三数之和 18. 四数之和

如果本题想难度升级:就是给出一个数组(而不是四个数组),在这里找出四个元素相加等于0,答案中不可以包含重复的四元组,大家可以思考一下,后续的文章我也会讲到的。之间的所有元素,从而可以快速查找是否存在满足条件的。**注意:**答案中不可以包含重复的三元组。请你找出并返回满足下述全部条件且。中始终包含了从当前固定第一个数。来存储数组中某些元素的。的作用是查找是否存在一个数。是通过在内层循环中逐个插入。,请你计算有多少个元组。,判断是否存在三元组。开始,到当前遍历位置。

2301_80170790的博客 704

黑猫带你学UFS协议第1篇:全网最全UFS协议中文详讲,这份学习框架图,你值得拥有!!!(持续更新中...)

本文由黑猫学长撰写,深入解析UFS协议,覆盖从基础概念到高级特性的全方位教程。适合存储芯片行业从业者和嵌入式开发者,旨在帮助读者快速掌握UFS协议,适用于高端智能手机、平板等智能设备。预计15万字,涵盖UFS 3.1协议,讲解UFS协议栈、物理层、链路层、传输层等内容。

黑猫奥利奥的博客 3687

代码随想录算法训练营第七天|454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

哈希2,双指针法是重点

Ustianan的博客 2103

ZeroClaw安装、使用方法详细全解

ZeroClaw 是一个用 Rust 编写的轻量级、高性能、完全自主的 AI 助手运行时框架

洛星核的博客 617

如何用Python打造PubMed API客户端:科研文献检索自动化实践

PubMed提供了官方的Entrez E-utilities API接口,支持程序化检索文献,但直接调用API需处理请求重试、参数封装、数据解析等问题。批量获取文献ID及结构化详情(标题、作者、DOI等)内置重试机制,应对网络波动或API限流统一数据输出格式,便于后续分析(如文献计量、AI文本处理)灵活适配不同检索需求(如指定数据库、结果数量)本文实现的PubMed API客户端,通过封装API请求、重试机制、数据解析,让科研文献检索从“手动点击”变为“代码自动化”。

ASKCOS博客 357

代码随想录算法训练营第七天|454四数相加II、 383赎金信、15三数之和、18四数之和

我们设想一下,我们当前的三数之和为 -3 < 0 那么我们如果移动橙色指针的话则会让我们的三数之和变的更小,因为我们的数组是有序的,所以我们移动橙色指针(蓝色不动)时和会变小,如果移动蓝色指针(橙色不动)的话,三数之和则会变大,所以这种情况则需要向右移动我们的蓝色指针,找到三数之和等于 0 的情况进行保存,如果三数之和大于 0 的话,则需要移动橙色指针,途中有三数之和为 0 的情况则保存。但是这里我们需要注意的一个细节就是,我们需要去除相同三元组的情况,我们看下面的例子。下面我们来看下三个指针的初始位置。

qq_43405634的博客 2029

YOLOv11改进 ,YOLOv11改进主干网络为MobileNetV3,助力涨点

MobileNetV3通过结合硬件感知网络架构搜索(NAS)和NetAdapt算法,通过新颖的架构改进进一步提升了性能。本文开始探讨了自动化搜索算法与网络设计如何协同工作,以利用互补方法来提升整体技术水平。通过这一过程,创建了两个新的MobileNet模型:MobileNetV3-Large和MobileNetV3-Small,分别针对高资源和低资源使用场景。这些模型随后被适配并应用于目标检测和语义分割任务。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1932

代码随想录算法训练营第七天 |【哈希表】454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

一般来说哈希表都是用来快速判断一个元素是否出现集合里。

qq_43714515的博客 2053

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

代码随想录算法训练营第七天 | 454.四数相加II ,383. 赎金信 ,15. 三数之和,18. 四数之和

数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。这时候就可以用到字典了。

懒羊羊在努力的博客 2314

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

代码随想录算法训练营第七天| 454 四数相加II、383 赎金信、15 三数之和、18 四数之和

刷题的时候还是得记得要多用空间换时间,时间复杂度优先。

m0_53877706的博客 393

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

代码随想录算法训练营第七天 | 454.四数相加II 、 383. 赎金信 、 15. 三数之和 、18. 四数之和

代码随想录算法训练营第七天 | 454.四数相加II 、 383. 赎金信 、 15. 三数之和 、18. 四数之和

qq_52421969的博客 1517

代码随想录算法训练营第七天 | 454.四数相加II 、 383. 赎金信、 15. 三数之和 、18. 四数之和

首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。定义int变量count,用来统计 a+b+c+d = 0 出现的次数。再遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。最后返回统计值 count 就可以了。

weixin_39877528的博客 419

7.15 代码随想录算法训练营第七天| 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

long定义sum来防止int上下限溢出,sum需要定义在while( left < right)内部,来保证sum每次循环重新计算。起初想的是外部的大while循环会限制 left < right,但是内部会优先越界访问造成无限循环,故需要在内部添加限制条件。即存在(1,1,-2)这样的三元组满足题意,但是如用set去重则会将这个答案也删去,故不行。2处 i>1的限制条件,一为防止i-1越界访问,二为了防止漏掉-1,-1,2 这种情况。其中,sum作为key键,[i, j]作为value来储存结果。

lampp0st的博客 441

代码随想录算法训练营第七天|LeetCode454.四数相加II、383.赎金信、15.三数之和、18.四数之和

代码随想录

tancxiaohei23的博客 321

代码随想录算法训练营第七天 | 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

第三章 哈希表part02。

qq_45488366的博客 388

代码随想录算法训练营第七天|Leetcode454 四数相加II、Leetcode383 赎金信、Leetcode15 三数之和、Leetcode18 四数之和

题目描述:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i!输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]进行去重的话,将会pass{0,0,0}进入结果集,导致返回结果不完全。输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

Demok123的博客 984

代码随想录算法训练营第七天 | 454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和

学习了哈希表的知识并进行了相关的应用训练,其中多次用到了双指针,加深了对双指针的理解。

m0_51795650的博客 1118

代码随想录算法训练营第七天 | Leetcode454四数相加II,Leetcode383赎金信,Leetcode15三数之和,Leetcode18四数之和

本题 思路整体和 三数之和一样的,都是双指针,但写的时候 有很多小细节,需要注意,建议先看视频。,也就是说如果输入是nums1 = [0,0], nums2 = [0,0], nums3 = [0,0], nums4 = [0,0],答案为2 x 2 x 2 x 2,即16。卡哥建议:本题虽然和 两数之和 很像,也能用哈希法,但用哈希法会很麻烦,双指针法才是正解,可以先看视频理解一下双指针法的思路,文章中讲解的,没问题。,也就是允许i = k + 1时,遍历的第一个nums[i]跟nums[k]数值相同。

鸽鸽鸽 888

代码随想录算法训练营第七天|LeetCode454 四数相加II、LeetCode383 赎金信、LeetCode15 三数之和、LeetCode18 四数之和

建议:本题是使用map 巧妙解决的问题,好好体会一下 哈希法 如何提高程序执行效率,降低时间复杂度,当然使用哈希法 会提高空间复杂度,但一般来说我们都是舍空间 换时间, 工业开发也是这样。建议:本题 和 242.有效的字母异位词 是一个思路 ,算是拓展题。

LCRbiubiubiu的博客 1296

代码随想录算法训练营第七天|454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

1. 使用哈希表。2. 前两个数组的和以及出现的次数作为键值对先存储。3. 检查后两个数组和的相反数有没有在哈希表中出现过,出现则获取次数。1. 解题思路和有效的字母异位词解法类似,使用数组(由于字符是有范围的,所以可以定义一个常量大小的数组,很大程度降低了空间复杂度)。1. 先对数组排序。2. 使用双指针法寻找当前和nums[i] 和为0的组合。3. 注意去重:1)对nums[i]去重;2)当找到满足和为0的三个数以后对下一个nums[left]和nums[right去重]。1. 使用指针法。

qq_39981702的博客 1239
上一篇: 代码随想录算法训练营第四天|24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、02.07. 链表相交 、142.环形链表II
studyingbear
博客等级 码龄5年 20粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值