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

代码随想录算法训练营Day6 | Leetcode 454四数相加II383赎金15三数之和18四数之和 Leetcode454四数相加II383赎金15三数之和18四数之和思路与技巧、代码 阅读详情

第454题.四数相加II

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

题目链接

视频链接

思路

看完代码随想录之后的思路:

避免使用4个连续的for,使得时间复杂度剧增。使用两个分开的双层for循环,溶蚀用哈希map表来进行高效查询

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

遇到的困难:

  1. unordered_map定义时一定要加上数据类型<int,int>
  2. 定义数据一定要令其等于0,否则会出现不可知的报错!int count=0
  3. 第二个循环中,寻找的是0-(c+d),此时已经没有a、b了,count+-也是与c、d有关,不能弄反了!!

383. 赎金信

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

题目链接

思路

打算使用集合哈希

看完代码随想录之后的思路:

因为只有小写字母,所以使用数组哈希就可以

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

暴力解法:

// 时间复杂度: O(n^2)
// 空间复杂度:O(1)
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        for (int i = 0; i < magazine.length(); i++) {
            for (int j = 0; j < ransomNote.length(); j++) {
                // 在ransomNote中找到和magazine相同的字符
                if (magazine[i] == ransomNote[j]) {
                    ransomNote.erase(ransomNote.begin() + j); // 因为需要找到对应元素的地址/索引,所以不能直接使用j
                    break;
                }
            }
        }
        // 如果ransomNote为空,则说明magazine的字符可以组成ransomNote
        if (ransomNote.length() == 0) {
            return true;
        }
        return false;
    }
};

遇到的困难:

两个数组相等是不用返回false,存在刚好相等的情况。

收获:

暴力解法中的收获:

在C++11及以后的标准中,auto关键字可以用来推断变量的类型。当使用auto定义变量时,编译器会根据变量初始化表达式的类型推断出该变量的类型。

auto x = 42;     // 推断x的类型为int
auto d = 3.14;   // 推断d的类型为double
auto s = "hello"; // 推断s的类型为const char*

std::vector是C++中的一个动态数组,支持erase()函数,可以使用该函数从向量中删除指定位置的元素。下面是一个使用erase()函数删除向量元素的例子:(find返回的是一个索引/地址

#include <iostream>
#include <vector>

int main() {
  std::vector<int> vec = {1, 2, 3, 4, 5};

  auto it = std::find(vec.begin(), vec.end(), 3);
  if (it != vec.end()) {
    vec.erase(it);  // 删除找到的元素
  }

  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i] << " ";  // 输出:1 2 4 5
  }

  return 0;
}

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

题目链接

视频链接

思路:

看完代码随想录之后的思路:

哈希map卡边界条件太麻烦,使用双指针法。

先排序,然后开始从左往右,移动首位i,每个i中移动左右两个指针,找合适的组合。

先算算数组中第i位是否大于0,否则直接结束;

去重a

当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()-2;i++)
        {
            if(nums[i]>0)return result;
            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++;
                    while(left<right&&nums[right]==nums[right-1])right--;
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
};

遇到的困难:

最后压栈的是一维向量,所有合起来是二维向量,不要压错类型

在找到合适的变量后,一定要记得把指针向后移动。去重只是把指针移到相同的位置上,结尾继续移动才能指向下一个不相同的。

收获:

 定义一个二维向量:

vector<vector<int>> result;

sort用于对指定范围内的元素进行排序。它通常用于对向量、数组或列表等容器进行排序,可以按升序或降序排列元素。参数为(第一个元素,最后一个元素)

重点:

对b和c的去重,不能放在前面两个判断和是否等于0的if else中,否则{000}就被pass掉了,一定是要取得一个结果之后再进行去重

关注a、bc的去重语句

第18题. 四数之和

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]

题目链接

视频链接

思路:

想用双指针,但是不知道第三个指针该指向何处

看完代码随想录之后的思路:

前面两个基础数用两层for循环,最后的两个数用双指针。此外,任意的n数之和都可以用这个方法,双指针可以将时间复杂度降一次。

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]>target&&nums[k]>=0)break;
            if(k>0&&nums[k]==nums[k-1])continue;
            for(int i=k+1;i<nums.size();i++)
            {
                if(nums[k]+nums[i]>target&&nums[i]>=0)break;
                if(i>k+1&&nums[i]==nums[i-1])continue;

                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++;
                        while(left>right&&nums[right]==nums[right-1])right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return result;
    }
};

遇到的困难:

  • k和i在for循环的中间语句中,不能为了省事把后面的数据个数减去,否则遇到不足量的数组,会出现错误。
  • 剪枝操作的结果应该是break,而不是return result。在i的for循环中,i、k和大于target后,下一个k还可能会有其他的i适配,不能直接return。
  • i、k剪枝的两个条件中,可以取一个等号,但不能同时都取等
  • 双指针的剪枝要注意,加上long,否则会溢出
  • 双指针的去重,注意要把left<right写上,否则出现相同的情况,会左右交叉

OpenCV 算法梳理分析 本文系统梳理了OpenCV的核心算法体系,从模块架构到具体函数实现。OpenCV采用分层设计,包含基础I/O、图像处理、特征检测、视频分析和智能算法五大层次,所有模块基于统一的Mat数据结构。重点分析了imgproc模块的8类图像处理算法(滤波、形态学、阈值化等),features2d模块的特征检测与匹配流程(SIFT/ORB等算法对比),以及objdetect、video、calib3d等模块的核心功能。针对不同场景提供了算法选型建议,如高斯噪声推荐GaussianBlur,特征匹配推荐ORB+Flann 阅读详情

相关推荐

Qwen 三代进化全景对比:从 Qwen2.5 到 Qwen3 再到 Qwen3.5

本文对比了阿里巴巴通义千问三代大模型(Qwen2.5、Qwen3、Qwen3.5)的技术演进。18个月内,模型在架构、训练数据和能力上实现显著突破:从纯稠密结构(Qwen2.5)发展为混合注意力架构(Qwen3.5),支持语言从29种扩展至201种,并实现原生多模态融合。关键进展包括引入MoE架构、Gated DeltaNet混合注意力机制(计算效率提升10倍)、以及从独立模态到早期视觉语言联合训练的转变。模型阵容从7个通用尺寸发展为8+个混合架构,最大参数量达397B,上下文窗口扩展至256K(托管版1M

m0_47999117的博客 1万+

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

初始做状态:不会本背景:本是 使用map 巧妙解决的问,好好体会一下 哈希法 如何提高程序执行效率,降低时间复杂度,当然使用哈希法 会提高空间复杂度,但一般来说我们都是舍空间 换时间, 工业开发也是这样。学完后想法:该听完好几遍依然没懂,日后还需再看,希望能比今日理解有所深入思路关键点:1.思路:仅仅遍历数组列表A,B, 取A,B中的数组元素a+b, 再遍历数组列表C,D,取C,D中的数组元素c+d,看是否符合a+b+c+d=0,符合就统计key对应出现的次数value。

weixin_64048829的博客 2671

北斗导航 | 从零开始学习基于奇偶矢量的接收机自主完好性监测(RAIM)算法及改进

接收机自主完好性监测(Receiver Autonomous Integrity Monitoring, RAIM)是GNSS接收机内部的一种算法,它仅利用冗余的伪距观测量来判断定位结果是否可靠、是否存在故障卫星,并能识别和排除故障卫星。奇偶矢量法是RAIM最经典的实现方式之一,它将不可直接观测的测量误差映射到一个“奇偶空间”中,使故障检测变得简单且服从精确的概率分布。w\mathbf{w}w虽然能反映故障,但它的协方差矩阵不是单位阵,各分量相关,不利于统计检验。奇偶矢量通过一个正交变换P。

尘世冰封的专栏 364

代码随想录算法训练营7|454.四数相加II383. 赎金、第15. 三数之和、第18. 四数之和。】

继续更新。

qq_44651829的博客 303

代码随想录算法训练营7|454.四数相加II |383. 赎金 |15. 三数之和 |18. 四数之和15号c++重写一遍)

总的来说map的算法,跟昨的两数之和比较接近。也是先把当前数,用HASH_FIND_INT(hash表,&要找的数,指针),有则次数++,若没有就放到hash表里面,下面34的双重循环继续找target-当前数的值,把符合次数的相加,最后return ans。

2401_83080774的博客 406

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

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。为了使问简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1。输出:2解法。

JAVaTTong的博客 68

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

454.四数相加II。第15. 三数之和

Chloe0123的博客 374

代码随想录算法训练营7 | 454.四数相加II383. 赎金15. 三数之和18. 四数之和

四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n^2),四数之和的时间复杂度是O(n^3)。涉及去重操作用哈希法不是很合适,可用双指针法。生成器表达式避免显式嵌套循环,提升可读性。替代手动初始化字典,代码更简洁。),将问转化为两数之和。将四个数组分为两组(

weixin_72471647的博客 191

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

哈希2,双指针法是重点

Ustianan的博客 2097

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

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

qq_43714515的博客 2042

小红书 算法一面 十一

例如 **Soft MoE** 采用这种方式,大幅提升负载均衡性,但会增加计算开销。- **熵正则化**:直接最大化门控概率分布的熵,熵越大表示分布越均匀,公式为 $\mathcal{L}_{ent} = -\frac{1}{N}\sum_{i=1}^N\sum_{k=1}^K p_{ik}\log p_{ik}$。- **核心原理**:源自 **GShard** 和 **Switch Transformer**,通过最小化专家选择概率分布的熵,迫使门控网络给每个专家分配相近的 token 数量。

XLYcmy的博客 438

数据库连接算法详解:从基础概念到嵌套循环优化

2.重复键在归并连接中的处理:排序归并连接遇到相同键时,需要保存或回溯同一键对应的记录组,然后输出笛卡尔积。(2)外连接:即使一方没有数据,也保留该侧数据,用NULL填充。对S中的键计算哈希值;(3)连接基数:连接结果的行数可能远大于任意一张输入表。设外表有R个页面,内表S个页面,比较次数O(R+R*S)5.哈希连接的限制:最适用于等值连接,不直接适用于比较。(1)build阶段:对较小的关系R建立哈希表。(1)内连接:只保留两张表之中能够匹配的内容。若R有M行,S有N行,则比较次数为O(MN)

jiangxiaohanya的博客 238

LeetCode 1. 两数之和 | 从暴力枚举到哈希表最优解 + 空间换时间思想全复盘

文章摘要 题目要求在数组中找到两数之和等于目标值的下标。核心思路是优化查找效率: 暴力法:双重循环枚举所有数对,时间复杂度O(n²),效率低但易实现。 哈希表优化:利用哈希表O(1)查找特性,遍历时存储已访问元素,每次计算差值并查询,时间复杂度降至O(n)。关键细节是先查后存,避免自匹配。 代码实现:哈希表法通过一次遍历完成,空间换时间,边界处理需注意空数组和不足两元素的情况。 常见错误:内层循环起始点、哈希表键值设计、立即返回结果等易错点需警惕。 面试要点:优先选择哈希表解法,解释与暴力法的差异,强调时间

yc2284238579的博客 259

算法日常・每日刷--<BFS>4

题目摘要: 给定一个由'X'和'O'组成的矩阵,要求捕获所有被'X'完全包围的'O'区域(即不与边界连通的区域),并将其替换为'X'。解法核心是逆向处理: 标记边界连通区域:遍历矩阵四边,对边界上的'O'进行BFS/DFS,标记所有与之连通的'O'为临时符号(如'.'),表示这些区域未被包围。 批量修改:遍历整个矩阵,将未被标记的'O'(被包围的)改为'X',同时恢复标记的'.'为'O'。 示例: 输入: [['X','X','X','X'], ['X','O','O','X'], ['X','X','O'

2503_92261635的博客 258

10.LeetCode算法讲解--滑动窗口--最大连续为一的个数

利用滑动窗口解决最大连续1的个数

Jammy_1的博客 221

AI辅助芯片制造:算法与工程化落地

《国产DRAM龙头长鑫科技上市创纪录,AI技术重塑芯片制造新范式》 国产DRAM龙头企业长鑫科技7月27日登陆科创板,创下3.31万亿元市值,成为A股"一哥"。作为大陆唯一实现DRAM大规模量产的IDM企业,长鑫科技标志着国产存储产业的重要突破。随着AI算力需求激增,DRAM市场迎来高速发展期。AI技术正在深度改变芯片制造模式,在工艺仿真、缺陷检测、设备维护等环节发挥关键作用,显著提升良率和效率。长鑫科技高管推荐的新书《AI辅助芯片制造:算法与工程化落地》系统解析了AI赋能半导体制造的实战方案

weixin_43178406的博客 1万+

二刷hot100-70.爬楼梯

dp数组初始化:dp[n+1];

2302_78497251的博客 50

S 曲线加减速算法完整详解(C# 原生实现,无第三方库)

S 曲线加减速是工业运动控制核心轨迹规划算法,相比梯形曲线,依靠约束加加速度 Jerk 实现加速度连续变化,有效消除机械冲击与振动。本文完整讲解七段式 S 曲线原理、阶段推演、时间预规划逻辑,剖析短行程自动裁剪等工程难点。提供无第三方依赖原生 C# 完整实现,内置运动状态机,支持正反方向运动,基于解析多项式实时求解位置、速度、加速度,无积分累积误差。代码可直接用于伺服上位机、模组轨迹发生器,亦可精简移植嵌入式平台。同时对比算法优劣与适用场景,适合工控开发、伺服调试、嵌入式运动算法学习者参考。

工业上位机开发工程师,专注C#底层算法与工控仪器开发。从零手写信号滤波、曲线拟合、机器视觉、排序与密码学哈希,纯原生实现零第三方库,附数学推导与可编译源码,可移植STM32/PLC。 982

Tokenization(分词算法):一切大语言模型的地基

本文深入解析了Tokenization(分词算法)这一大语言模型的基础技术。Tokenization将原始文本切分为模型可处理的子词单元并映射为数字ID,是模型理解文本的第一步。

2301_80194949的博客 200

【升级U8+】不能将值 NULL 插入列 ‘VT_ID‘,表 ‘VoucherItems‘;列不允许有 Null 值。

不能将值 NULL 插入列 ‘VT_ID’,表 ‘UFDATA_006_2012.dbo.VoucherItems’;列不允许有 Null 值。INSERT 失败。

努力不懈的为广大客户提供优质的产品与真诚、贴心、专业的服务! 457

MCP2517FD/MCP2518FD通用CAN FD驱动源码包(C语言,支持I2C-SPI透明桥接)

这个驱动包专为Microchip MCP2517FD和MCP2518FD CAN FD控制器设计,采用纯C实现,不依赖特定硬件平台。核心特点是软硬分离:驱动层只负责寄存器配置、状态检查和通协议封装,物理层交互(如SPI或经I2C转SPI的访问)通过可替换的接口函数完成,因此无需修改驱动代码即可适配不同总线方案。支持自动识别连接的是MCP2517FD还是MCP2518FD芯片,并为每个设备实例提供独立配置能力。资源包含完整源文件(MCP251XFD.c/h)、配置模板(Conf_MCP251XFD_Template.h)、错误定义(ErrorsDef.h)、配套CRC校验模块(CRC16_USB/CMS/CAN系列)、同步模式工程文件(.sln/.cproj)、详细PDF使用指南(v1.0.0同步驱动版)以及单元测试和文档目录。开箱即用,只需将MCP251XFD.c、MCP251XFD.h、Conf_MCP251XFD_Template.h和ErrorsDef.h加入项目,重命名配置模板后按需填充引脚、时序和通接口函数即可运行。适用于STM32、ESP32、NXP等主流MCU平台的嵌入式CAN FD应用开发。

上一篇: 代码随想录算法训练营第六天|242.有效的字母异位词、349. 两个数组的交集、第202题. 快乐数、1. 两数之和
下一篇: 代码随想录算法训练营第8天|344. 反转字符串、541. 反转字符串 II、剑指Offer 05.替换空格、151. 反转字符串中的单词、剑指 Offer 58 - II. 左旋转字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值