牛客 BM1: 反转链表

目录

一、题目

二、C++解题程序框架

1. 结构体定义

2. 类定义

3. 输入输出说明

三、链表指针

1. 链表指针的基本概念

2. 链表指针的常见操作

1. 遍历链表

2. 插入节点

3. 删除节点

3. 链表指针操作的注意事项

4. 总结

四、解题

方法一:迭代法

方法二:递归法

一、题目

二、C++解题程序框架

/*** struct ListNode {*	int val;*	struct ListNode *next;*	ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <cstddef>
#include <cstdio>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param head ListNode类 * @return ListNode类*/ListNode* ReverseList(ListNode* head) {// write code here}
};

这段代码是一个C++程序的框架,以下是对代码的详细解释:

1. 结构体定义

struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(nullptr) {}
};
  • ListNode 是一个结构体,用于表示链表中的节点。

  • 每个节点包含两个成员:

    • int val:存储节点的值。

    • struct ListNode *next:指向下一个节点的指针。

  • 构造函数 ListNode(int x) 用于初始化节点的值为 x,并将 next 指针初始化为 nullptr

2. 类定义

class Solution {
public:ListNode* ReverseList(ListNode* head) {// write code here}
};
  • Solution 是一个类,包含一个公共方法 ReverseList

  • 方法 ReverseList 的作用是反转链表。

    • 参数 ListNode* head:表示链表的头节点。

    • 返回值 ListNode*:返回反转后的链表的头节点。

3. 输入输出说明

  • 输入:链表的头节点 head

    • 例如,链表 1 -> 2 -> 3 -> nullptr 的头节点是 head

  • 输出:反转后的链表的头节点。

    • 对于上述输入,输出应为链表 3 -> 2 -> 1 -> nullptr 的头节点。

三、链表指针

在链表操作中,指针是一个非常重要的概念。链表是由一系列节点组成的,每个节点包含两部分:数据(val和)指向下一个节点的指针(next)。通过指针的操作,我们可以实现链表的遍历、插入、删除等操作。

1. 链表指针的基本概念

在链表中,指针用于连接各个节点。例如,对于一个简单的单链表,每个节点的 next 指针指向下一个节点,最后一个节点的 next 指针通常为 nullptr,表示链表的结束。

2. 链表指针的常见操作

1. 遍历链表

遍历链表是链表操作中最基本的操作之一。通过指针逐个访问链表中的每个节点。

void PrintList(ListNode* head) {ListNode* current = head; // 使用一个指针指向当前节点while (current != nullptr) { // 当指针不为空时继续遍历printf("%d -> ", current->val); // 打印当前节点的值current = current->next; // 移动指针到下一个节点}printf("nullptr\n"); // 表示链表结束
}

2. 插入节点

在链表中插入节点通常需要修改指针的指向。例如,插入一个新节点到链表的头部、尾部或中间。

  • 插入到头部

void InsertAtHead(ListNode*& head, int value) {ListNode* newNode = new ListNode(value); // 创建一个新节点newNode->next = head; // 新节点的 next 指向原头节点head = newNode; // 更新头指针
}
  • 插入到尾部

void InsertAtTail(ListNode*& head, int value) {ListNode* newNode = new ListNode(value); // 创建一个新节点if (head == nullptr) { // 如果链表为空,直接将新节点作为头节点head = newNode;} else {ListNode* current = head; // 使用一个指针指向当前节点while (current->next != nullptr) { // 找到链表的最后一个节点current = current->next;}current->next = newNode; // 将新节点插入到尾部}
}

3. 删除节点

删除链表中的节点也需要操作指针。例如,删除链表中的特定某个值的节点。

void DeleteNode(ListNode*& head, int value) {if (head == nullptr) return; // 如果链表为空,直接返回// 如果头节点就是要删除的节点if (head->val == value) {ListNode* temp = head; // 保存头节点head = head->next; // 更新头指针delete temp; // 释放原头节点的内存return;}// 遍历链表,找到要删除的节点的前一个节点ListNode* current = head;while (current->next != nullptr && current->next->val != value) {current = current->next;}// 如果找到了要删除的节点if (current->next != nullptr) {ListNode* temp = current->next; // 保存要删除的节点current->next = current->next->next; // 修改指针,跳过要删除的节点delete temp; // 释放内存}
}

3. 链表指针操作的注意事项

  1. 指针的初始化:在操作链表时,指针需要正确初始化,避免野指针。

  2. 指针的更新:在修改指针时,要确保不会丢失对链表的引用,避免内存泄漏。

  3. 边界条件:处理链表为空或只有一个节点的情况,避免程序出错。

  4. 内存管理:在删除节点时,记得释放节点占用的内存,避免内存泄漏。

4. 总结

链表操作的核心是通过指针来连接和操作节点。指针的正确使用是实现链表各种操作的基础。通过熟练掌握指针的操作,可以高效地实现链表的遍历、插入、删除和反转等功能。

四、解题

方法一:迭代法

ListNode* ReverseList(ListNode* head) {ListNode* prev = nullptr; // 前一个节点ListNode* curr = head;    // 当前节点while (curr != nullptr) {ListNode* nextTemp = curr->next; // 保存下一个节点curr->next = prev;               // 反转当前节点的指针       prev = curr;                     // 移动 prev 到当前节点curr = nextTemp;                 // 移动 curr 到下一个节点}return prev; // 最终 prev 指向新的头节点
}

方法二:递归法

ListNode* ReverseList(ListNode* head) {if (head == nullptr || head->next == nullptr) {return head; // 如果链表为空或只有一个节点,直接返回}ListNode* newHead = ReverseList(head->next); // 递归反转后续链表head->next->next = head;                     // 将当前节点的下一个节点的 next 指向当前节点head->next = nullptr;                        // 当前节点的 next 指向 nullptrreturn newHead;                              // 返回新的头节点
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/69567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MIT开源7B推理模型Satori:用行动思维链进行强化学习,增强自回归搜索

自OpenAI的o1发布以来&#xff0c;研究社区为提升开源LLM的高级推理能力做出了诸多努力&#xff0c;包括使用强大的教师模型进行蒸馏、蒙特卡洛树搜索&#xff08;MCTS&#xff09;以及基于奖励模型的引导搜索等方法。 本研究旨在探索一个新的研究方向&#xff1a;使LLM具备自回…

Kubernetes控制平面组件:etcd(一)

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;kubectl 和 …

Django在终端创建项目(pycharm Windows)

1.选择目录 选择或新建一个文件夹&#xff0c;作为项目保存的地方 2.右键在终端打开 3.确定django-admin.exe安装位置 找到自己安装django时&#xff0c;django-admin.exe安装的位置&#xff0c;例如 4.运行命令 使用django-admin.exe的绝对路径&#xff0c;在刚才打开的终端…

e2studio开发RA2E1(9)----定时器GPT配置输入捕获

e2studio开发RA2E1.9--定时器GPT配置输入捕获 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback…

【PS 2022】Adobe Genuine Service Alert 弹出

电脑总是弹出Adobe Genuine Service Alert弹窗 1. 不关掉弹窗并打开任务管理器&#xff0c;找到Adobe Genuine Service Alert&#xff0c;并右键进入文件所在位置 2 在任务管理器中结束进程并将文件夹中的 .exe 文件都使用空文档替换掉 3. 打开PS不弹出弹窗&#xff0c;解决&a…

RoboGrasp:一种用于稳健机器人控制的通用抓取策略

25年1月来自北京大学和哈佛大学的论文“RoboGrasp: A Universal Grasping Policy for Robust Robotic Control”。 模仿学习和世界模型在推进通用机器人学习方面显示出巨大的潜力&#xff0c;而机器人抓取仍然是实现精确操控的关键挑战。现有方法通常严重依赖机械臂状态数据和…

接口测试Day12-持续集成、git简介和安装、Gitee远程仓库、jenkins集成

持续集成 概念&#xff1a; 团队成员将自己的工作成果&#xff0c;持续集成到一个公共平台的过程。成员可以每天集成一次&#xff0c;也可以一天集成多 次。 相关工具&#xff1a; 本地代码管理&#xff1a;git远程代码管理&#xff1a;gitee(国内)、github(国外)、gitlib(公司…

C语言基础11:分支结构以及if的使用

C语言基础 内容提要 分支结构 条件判断用if语句实现分支结构 分支结构 问题抛出 我们在程序设计往往会遇到如下问题&#xff0c;比如下面的函数的计算&#xff1a; y { 1 / x 当 x ≠ 0 时 10000 当 x 0 时 y \begin{cases} 1/x \quad当x\neq0时\\ \\ 10000 \quad当x0…

81页精品PPT | 华为流程与信息化实践与架构规划分享

华为流程与信息化实践与架构规划分享主要围绕华为在业务流程与信息化建设方面的经验、企业架构规划方法以及企业数字化转型路径展开。华为通过持续的业务变革和信息化建设&#xff0c;从本土企业逐步发展为国际化、全球化企业&#xff0c;其管理体系以持续创新和世界级管理体系…

【最大开支——优先队列,计算增量】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; using pll pair<ll, int>; #define x first #define y second const int N 1e5 10; int n, m; int k[N], b[N], cnt[N]; priority_queue<pll, vector<pll>> pq; // d…

174款复古Y2K酸性镀铬银色金属多样化锁链链条铁链几何抽象PNG免扣元素设计套装 Studio 2AM - Chains

Chains 是以链条纹理为主题的设计元素的集合。以 PNG 格式以高分辨率创建&#xff0c;但文件大小较小&#xff0c;因此不会占用硬盘空间。“Chains” 是以 PNG 格式提供的以链条为主题的设计元素的高分辨率集合。该套装包括 174 个银色、生锈和彩虹色材料的链条纹理&#xff0c…

将 AMD Zynq™ RFSoC 扩展到毫米波领域

目录 将 AMD Zynq™ RFSoC 扩展到毫米波领域Avnet XRF RFSoC 系统级模块适用于 MATLAB 的 Avnet RFSoC Explorer 工具箱5G mmWave PAAM 开发平台突破性的宽带毫米波波束成形特征&#xff1a;OTBF103 Mathworks Simulink 模型优化毫米波应用中的射频信号路径 用于宽带毫米波上/下…

IDEA中打包maven项目,提示Compilation failure

使用IDEA打包maven项目&#xff0c;报错如下&#xff1a; 解决方法&#xff1a;在pom文件中指定JDK版本即可 <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target> </propertie…

Idea集成deepseek生成代码

今天我带大家在idea上安装CodeGpt插件&#xff0c;这个插件可以根据我们的提示词生产代码&#xff0c;我们一起试试。 1、安装插件 打开idea&#xff0c;再点击setting菜单&#xff0c;按以下步骤操作。 安装完成后&#xff0c;一定要点击第四步“ok”。再次点击菜单setting…

C++STL(六)——list模拟

目录 本次所需实现的三个类一、结点类的模拟实现构造函数 二、迭代器类的模拟实现为什么有迭代器类迭代器类的模板参数说明构造函数运算符的重载- -运算符的重载和!运算符的重载*运算符的重载->运算符的重载引入模板第二个和第三个参数 三、list的模拟实现3.1 默认成员函数构…

Ubuntu安装PgSQL17

参考官网教程&#xff0c;Ubuntu24 apt在线安装Postgres 17 1. 要手动配置 Apt 存储库 # 导入存储库签名密钥&#xff1a; sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo curl -o /usr/share/postgresql-common/pgdg/apt…

【iOS自动化】Xcode配置WebDriverAgent

WebDriverAgent 是 iOS 端自动化测试的工具&#xff0c;这里记录下 MacOS 环境 Xcode 如何配置 WebDriverAgent。 【重要】环境准备 ‼️ 注意&#xff1a;Xcode 版本需要支持对应的 iOS 版本&#xff0c;而 Xcode 版本又依赖 MacOS 版本&#xff1b;在开始部署前&#xff0c…

Golang:精通sync/atomic 包的Atomic 操作

在本指南中&#xff0c;我们将探索sync/atomic包的细节&#xff0c;展示如何编写更安全、更高效的并发代码。无论你是经验丰富的Gopher还是刚刚起步&#xff0c;你都会发现有价值的见解来提升Go编程技能。让我们一起开启原子运算的力量吧&#xff01; 理解Go中的原子操作 在快…

Mp4视频播放机无法播放视频-批量修改视频分辨率(帧宽、帧高)

背景 家人有一台夏新多功能 视频播放器(夏新多功能 视频播放器),用来播放广场舞。下载了一些广场舞视频, 只有部分视频可以播放,其他视频均无法播放,判断应该不是帧速率和数据速率的限制, 分析可能是播放器不支持帧高度大于720的视频。由于视频文件较多,需要借助视频编…

【Python】字典

个人主页&#xff1a;GUIQU. 归属专栏&#xff1a;Python 文章目录 1. 字典概述2. 字典的创建与初始化2.1 直接使用花括号创建2.2 使用 dict() 构造函数创建2.3 字典推导式创建 3. 字典的基本操作3.1 访问字典中的值3.2 修改和添加键值对3.3 删除键值对 4. 字典的遍历4.1 遍历键…