当前位置: 首页 > news >正文

LeetCode:经典题之21、24 题解及延伸

系列目录

88.合并两个有序数组
52.螺旋数组
567.字符串的排列
643.子数组最大平均数
150.逆波兰表达式
61.旋转链表
160.相交链表
83.删除排序链表中的重复元素
389.找不同
1491.去掉最低工资和最高工资后的工资平均值
896.单调序列
206.反转链表
92.反转链表II
141.环形链表
142.环型链表


目录

  • 系列目录
  • 21. 合并两个有序列表
  • 24. 两两交换链表中的节点
    • 内存泄漏 (Memory Leak ):


⚠️小tips

一般处理链表问题

相比迭代,递归算法更容易想到,但空间复杂度更高

而迭代仅需常数级的空间复杂度≈O(1),但有时会有些费脑子

21. 合并两个有序列表

🌟链表+递归+迭代

原题链接


C++
若未特殊标明,以下题解均写用C++

方法一 递归
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/// 宏定义没有 ;分号
#define list1 l1
#define list2 l2class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {if (l1 == nullptr) return l2;else if (l2 == nullptr)return l1;else if (l1->val <= l2->val) {// 比较 l1->next 和 刚刚参与比较的 l2l1->next = mergeTwoLists(l1->next, l2);// 还要继续利用原 l1找到l1.next,所以后返回 l1return l1;} else {// 同理l2->next = mergeTwoLists(l2->next, l1);return l2;}}
};

方法二 迭代
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/// 注意顺序不要反了,原名在前# define list1 l1# define list2 l2
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {// 定义一个哨兵💂 快速返回合并后的链表// 不妨定义值为 -1 ListNode* dummyHead = new ListNode(-1);// 维护(preserve)一个 prev指针,让其移动ListNode* prev = dummyHead;while (l1 != nullptr && l2 != nullptr) {if (l1->val <= l2->val) {prev->next = l1;l1 = l1->next;} else {prev->next = l2;l2 = l2->next;}// 调整 prev的位置prev = prev->next;}// l1 或 l2 定会有一个先指向空// 三元条件运算符prev->next = l1 == nullptr ? l2 : l1;return dummyHead->next;}
};

有关三元条件运算符 和 哨兵(哑节点/虚拟头节点)可以参考这篇文章





24. 两两交换链表中的节点

🌟链表+递归+迭代
原题链接


C++
若未特殊标明,以下题解均写用C++

方法一 递归
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* swapPairs(ListNode* head) {// 相邻节点两两交换,原链表第2个节点即新链表的第1个节点// 而newHead->next 又恰为除去这两个节点的链表的头节点// 且swapParis() 的变量是链表的 头节点// 故可以递归地完成两两交换// 如果链表长度为 0或1,无法交换——不如说无需交换if (head == nullptr || head->next == nullptr)return head;ListNode *newHead = head->next;head->next = swapPairs(newHead->next);newHead->next = head;// newHead 为交换后链表的头节点return newHead;}
};

方法二 迭代
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* swapPairs(ListNode* head) {// new一个 虚拟头节点ListNode* dummy = new ListNode(0);dummy->next = head;// 定义临时(temporary)节点 temp,记录尚未处理好的链表的头节点ListNode* temp = dummy;while (temp->next != nullptr && temp->next->next != nullptr) {// 定义 node1(节点1) 和 node2ListNode* node1 = temp->next;ListNode* node2 = temp->next->next;temp->next = node2;node1->next = node2->next;// 用完再更新 node2node2->next = node1;// 记得更新 temp// 指针跟着节点走的temp = node1;}// 记得删除这个 dummyListNode *res = dummy->next;delete dummy;return res;}
};

内存泄漏 (Memory Leak ):

内存泄漏是指程序在申请内存后,未能正确地释放它,导致系统内存的浪费,甚至在运行时占用越来越多的内存,使程序崩溃甚至可能导致系统可用内存耗尽而变得不稳定

对于任何动态内存分配的问题,处理好内存泄漏是非常必要的

为了避免内存泄漏,可以采取以下措施:

  1. 确保每个new都有对应的delete:每当使用new来创建一个节点时,都应该确保在适当的时候使用delete来释放它 这通常发生在节点不再需要时,例如在删除节点或链表被销毁时
  2. 使用智能指针:C++11及以后的版本引入了智能指针 (如unique_ptrshared_ptr ),它们可以自动管理内存,并在适当的时候释放它 使用智能指针可以大大简化内存管理,并减少内存泄漏的风险
  3. 避免野指针:野指针是指已经被释放但仍然被引用的指针 如果试图通过野指针访问内存或释放已经释放的内存,都会导致不可预测的行为,包括内存泄漏 因此,应该确保在释放内存后立即将指针设置为nullptr,以避免野指针的问题
  4. 使用RAII (Resource Acquisition Is Initialization )原则:RAII是一种编程技术,它要求将资源的生命周期与对象的生命周期绑定在一起 通过这种方法,可以确保在对象不再需要时自动释放其占用的资源,包括内存
  5. 进行内存泄漏检测:使用工具 (如Valgrind、AddressSanitizer等 )来检测内存泄漏 这些工具可以帮助你发现潜在的内存泄漏问题,并提供有关如何修复它们的建议

相关文章:

LeetCode:经典题之21、24 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …...

【C++11】initializer_list详解!

一、什么是initializer_list? nitializer_list 是一种C11新的类型特性&#xff0c;它允许我们以统一的方式初始化对象。它是一个代表数组的轻量级包装器&#xff0c;通常用于构造函数和函数参数中&#xff0c;以允许传递一个初始化元素列表。 initializer_list也是一种模板类…...

如何在Java中处理UnsupportedOperationException异常?

如何在Java中处理UnsupportedOperationException异常&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java编程中&#xff0c;我们经常会遇到各…...

WPS没保存关闭了怎么恢复数据?4个方法(更新版)

想象一下&#xff0c;你正在用WPS奋笔疾书&#xff0c;灵感如泉水般涌出&#xff0c;突然间&#xff0c;电脑却跟你开了个玩笑——啪地一下&#xff0c;文档未保存就关闭了&#xff01;是不是感觉像是被泼了一盆冷水&#xff0c;所有的热情瞬间熄灭&#xff1f;别急&#xff0c…...

elementplus el-table(行列互换)转置

Element Plus v2.4.0, repl v3.4.0 <template> <div><el-table :data"tableData" style"width: 100%"><el-table-column prop"name" label"名字" width"180" /><el-table-column prop"wei…...

Gradle 核心之 Task

一、前言 只有 Task 才可以在 Gradle 的执行阶段去执行&#xff08;其实质是执行的 Task 中的一系列 Action&#xff09;&#xff0c;所以 Task 的重要性不言而喻。 二、Task 2.1 Task 定义与配置 Task 的定义方式有如下两种&#xff1a; Task 的配置方式也有如下两种&#xf…...

【React 】折叠面板,点击展开时再请求数据

需求背景&#xff1a;使用折叠面板的形式展示数据&#xff0c;面板内部数据需要在打开时请求接口获取。 遇到问题&#xff1a;最开始使用Antd 的折叠面板组件&#xff0c;它对于数据直接渲染是没问题的&#xff0c;但是不好满足打开面板时再动态加载数据的需求&#xff0c;于是…...

c++学习 文件操作,模板

文件操作 #include<iostream> #include<string> #include<fstream> using namespace std; //文本操作 //程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放 //通过文件可以数据持久化 //c中对文件操作包含头文件<fstream> /…...

开源与在线 M3U8 Downloader 项目介绍及使用指南

M3U8 是一种用于播放列表格式的文件类型&#xff0c;广泛应用于流媒体服务中&#xff0c;特别是 HLS&#xff08;HTTP Live Streaming&#xff09;协议。它包含了一系列的 TS&#xff08;Transport Stream&#xff09;视频片段地址&#xff0c;使得视频能够分段加载&#xff0c…...

正则表达式与文本处理器

正则表达式 基础正大表达式 查看特定字符 grep grep-n the test.txt grep-in the test.txt-n 显示行号 -i 不区分大小写 -v 反转查找 [] &#xff1a;中括号里可以写元素&#xff0c;内容符合任意元素&#xff0c;就会过滤出来 ^ :写在中括号里&#xff0c;代表取反。以^开头&…...

RedisTemplate方法一览表

数据类型RedisTemplate 方法Redis命令解释应用场景stringopsForValue().set(key, value)SET设置存储在指定 key 下的值存储简单数据&#xff0c;如用户的设置、配置项opsForValue().get(key)GET获取存储在指定 key 下的值读取存储的数据&#xff0c;如用户信息、配置参数opsFor…...

个人对devops的一点见解

DevOps 是一种将开发&#xff08;Development&#xff09;和运维&#xff08;Operations&#xff09;相结合的理念和实践方法。 它强调打破开发团队和运维团队之间的传统壁垒&#xff0c;促进两个团队之间更紧密的协作和沟通&#xff0c;以实现更高效、更快速、更可靠的软件交付…...

HarmonyOS鸿蒙应用开发基础知识

参考 HarmonyOS鸿蒙应用开发 (二、应用程序包结构理解及Ability的跳转&#xff0c;与Android的对比)_hap(harmonyos ability package)包的开发-CSDN博客 HarmonyOS NEXT下一代编程语言仓颉介绍及入门-CSDN博客...

Halcon 根据霍夫变换在图像中寻找直线

一 霍夫变换 1 定义 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一.几何形状包括圆&#xff0c;椭圆&#xff0c;直线等等. 2 直线方程 直线的方程可以用yk*xb 来表示&#xff0c;其中k和b是参数&#xff0c;分别是斜率和截距; 3 霍夫变换原理&#xff1a; 设…...

基于Openmv的追小球的云台

介绍 在这篇文章&#xff0c;我会先介绍需要用到且需要注意的函数&#xff0c;之后再给出整体代码 在追小球的云台中&#xff0c;比较重要的部分就是云台&#xff08;实质上就是舵机&#xff09;的控制以及对识别的色块位置进行处理得到相应信息后控制云台进行运动 1、舵机模…...

关于scrapy模块中setting.py文件的介绍

作用 在Scrapy框架中&#xff0c;settings.py 文件起着非常重要的作用&#xff0c;它用于配置和控制整个Scrapy爬虫项目的行为、性能和功能。 setting.py文件的介绍 # Scrapy settings for haodaifu project # # For simplicity, this file contains only settings consider…...

laravel Blade 指令的趣味性

首先&#xff0c;我们通过几个要点来解释 Blade 引擎的工作原理。 您选择一个 Blade 模板进行渲染。引擎使用一系列正则表达式来解析和编译模板。该引擎生成一个普通的 PHP 文件并将其写入磁盘&#xff08;以便将其缓存以供将来渲染&#xff09;。包含 PHP 文件并使用输出缓冲…...

【面试题】等保(等级保护)的工作流程

等保&#xff08;等级保护&#xff09;的工作流程主要包括以下几个步骤&#xff0c;以下将详细分点介绍&#xff1a; 系统定级&#xff1a; 确定定级对象&#xff1a;根据《信息系统等级保护管理办法》和《信息系统等级保护定级指南》的要求&#xff0c;确定需要进行等级保护的…...

python调用麦克风和扬声器,并调用阿里云实时语音转文字

import time import queue import sounddevice as sd import numpy as np import nls import sys# 阿里云配置信息 URL "wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1" TOKEN "XXXX" # 参考https://help.aliyun.com/document_detail/450255.html获…...

描述在React中集成第三方库(如Redux或React Router)的常见模式。

在React中集成第三方库&#xff0c;如状态管理库Redux或路由库React Router&#xff0c;通常遵循一些常见的模式和最佳实践。下面是一些集成这些库的步骤和模式&#xff1a; 集成Redux 安装Redux及相关包: 安装Redux及其中间件&#xff08;如redux-thunk或redux-saga&#xf…...

门店小程序怎么运营

门店小程序怎么运营门店小程序怎么运营我接触过不少开了门店小程序的老板&#xff0c;上线的时候都挺兴奋&#xff0c;觉得”终于有自己的线上渠道了”。但过了一个月再看&#xff0c;大部分人的小程序就像挂在门口的招牌——有&#xff0c;但没什么人看。门店小程序跟纯线上商…...

悬而未决:Nacos 与 Apollo 能否终结“改配置就要重启”的诅咒?

写在前面“你把 log-level 从 INFO 改成 DEBUG 了&#xff1f;行&#xff0c;我记一下。等下次发布的时候一起上线。”这句话&#xff0c;是不是很熟悉&#xff1f;在一个超过 5 年的大型微服务项目中&#xff0c;我见过太多这样的场景&#xff1a;开发团队在线上环境排查问题时…...

从零实现MD5算法:C语言详解与工程实践指南

1. 从零开始&#xff1a;为什么我们需要自己实现MD5&#xff1f;在信息安全领域&#xff0c;MD5&#xff08;Message-Digest Algorithm 5&#xff09;是一个绕不开的名字。尽管它早已被证明存在碰撞漏洞&#xff0c;不再适用于高安全级别的数字签名或证书场景&#xff0c;但它在…...

深入解析JavaScript Promise类型检测:从原理到who-is-actor库实战

1. 项目概述&#xff1a;从“演员是谁”到代码世界的身份识别最近在GitHub上看到一个挺有意思的项目&#xff0c;叫who-is-actor&#xff0c;作者是Wscats。光看名字&#xff0c;你可能会以为这是个娱乐八卦工具&#xff0c;用来查某个明星是谁。但实际上&#xff0c;这是一个非…...

基于MCP协议为AI智能体赋予本地桌面自动化能力

1. 项目概述&#xff1a;为AI智能体赋予“手和眼”的桌面操作技能如果你正在使用像Cursor、Claude Code或Codex这类AI编程助手&#xff0c;可能会发现一个痛点&#xff1a;它们能帮你写代码、分析问题&#xff0c;但无法直接操作你的电脑。你想让它帮你打开一个软件、填写一个表…...

Sora 2 × YouTube双平台协同工作流:自动生成多尺寸横竖版+智能章节标记+CC字幕同步(仅需1次Prompt)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Sora 2 YouTube双平台协同工作流全景概览 Sora 2 作为新一代多模态生成引擎&#xff0c;已原生支持高保真视频结构化输出与语义时间轴标注&#xff1b;YouTube 则通过 Creator Studio API 和 Data API…...

偏移重载双缸同步电液伺服控制【附代码】

✨ 长期致力于电液伺服系统、双缸同步、联合仿真、力/位切换控制、模糊RBF神经网络PID控制研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;双缸力/位切…...

Ricon组态系统:工业组件开发指南与实践

一、引言 Ricon组态系统内置200工业组件和图元&#xff0c;涵盖基础组件、图表组件、电气图元、动画组件等。本文将介绍如何基于Ricon平台开发自定义组件。 演示地址&#xff1a;http://1.15.10.177/ 二、组件体系架构 2.1 组件分类 类别组件示例用途基础组件文本、矩形、…...

SkillHarness:轻量级技能编排框架,构建可维护的AI与自动化工作流

1. 项目概述&#xff1a;一个面向开发者的技能编排与自动化框架最近在和一些做AI应用开发的朋友交流时&#xff0c;大家普遍提到一个痛点&#xff1a;当你想把多个AI模型、工具或者API串联起来&#xff0c;完成一个稍微复杂点的任务时&#xff0c;比如“分析一篇技术文章&#…...

Open Liberty Docker镜像深度解析:企业级Java应用容器化部署实战

1. 项目概述&#xff1a;一个企业级Java应用服务器的开源镜像 如果你在Java企业级应用开发领域摸爬滚打过几年&#xff0c;尤其是和WebSphere家族的产品打过交道&#xff0c;那么“Liberty”这个名字你一定不陌生。它代表着一种轻量、快速、模块化的Java EE&#xff08;现在叫J…...