牛客 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 和 …

Express 中间件

在构建 Web 应用程序时&#xff0c;中间件&#xff08;Middleware&#xff09;扮演着至关重要的角色。它允许你定义一系列的函数来处理 HTTP 请求和响应过程中的各种任务。Express.js 是 Node.js 上最流行的框架之一&#xff0c;以其简洁且强大的中间件机制著称。本文将深入探讨…

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

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

Android 常用设计模式和实例

一、什么是设计模式&#xff1f; 设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问&#xff0c;设计模式于己于他人于系统都是多赢的&#xff0c;设计模式使代码编制真正工程化&#xff0c;设计模式是软件工程的基石&#xff0c;如同大厦的一块块…

跨平台开发利器:UniApp 全面解析与实践指南

文章目录 一、UniApp 是什么&#xff1f;核心优势&#xff1a; 二、核心特性解析1. 跨端原理2. 技术架构3. 主要功能特性 三、开发环境搭建1. 必备工具2. 项目创建3. 目录结构 四、开发实践指南1. 页面开发示例2. 跨端API调用3. 条件编译实战 五、性能优化技巧1. 启动速度优化2…

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

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

【Java】MyBatis动态SQL

在MyBatis中使用动态SQL语句。 动态SQL是指根据参数数据动态组织SQL的技术。 生活中的案例&#xff1a; 在京东上买东西时&#xff0c;用户搜索商品&#xff0c;可以选择筛选条件&#xff0c;比如品牌&#xff0c;价格&#xff0c;材质等&#xff0c;也可以不使用筛选条件。这时…

【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(公司…

pytest测试专题 - 1.1 运行pytest

<< 返回目录 1 pytest学习笔记 - 1.1 运行pytest 1.1 运行pyest 在命令行执行pytest --help usage: pytest [options] [file_or_dir] [file_or_dir] [...] ... ...1.1.1 pytest不携带参数 pytest不带参数时&#xff0c;会扫描当前目录下的所有目录、子目录中符合测试用…

Django REST Framework:如何获取序列化后的ID

Django REST Framework&#xff1a;如何获取序列化后的ID &#x1f604; 嗨&#xff0c;小伙伴们&#xff01;今天我们来聊一聊Django REST Framework&#xff08;简称DRF&#xff09;中一个非常常见的操作&#xff1a;如何获取序列化后的ID。对于那些刚入门的朋友们&#xff…

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…

利用navicat 17 实现两个不同数据库oracle和sqlserver2008之间多个表数据的自动同步

要实现两个不同数据库&#xff08;Oracle 和 SQL Server 2008&#xff09;之间多个表数据的自动同步&#xff0c;可以利用 Navicat 17 的“数据传输”功能&#xff08;Data Transfer&#xff09;和“任务调度”功能&#xff08;Task Scheduler&#xff09;。下面是一个概括的步…

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

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

智能客服API接口:提升电商平台用户体验的新途径

在数字化时代&#xff0c;电商平台已成为人们购物的主要渠道之一。随着用户需求的日益多样化和个性化&#xff0c;电商平台面临着前所未有的挑战&#xff0c;即如何在激烈的市场竞争中脱颖而出&#xff0c;提供卓越的用户体验。智能客服API接口作为连接电商平台与智能客服系统的…

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

题目 代码 #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 模型优化毫米波应用中的射频信号路径 用于宽带毫米波上/下…