【一刷《剑指Offer》】面试题 16:反转链表

news2024/11/25 7:12:43

力扣对应题目链接:206. 反转链表 - 力扣(LeetCode)

牛客对应题目链接:反转链表_牛客题霸_牛客网 (nowcoder.com)

核心考点 :链表操作,思维缜密程度。

一、《剑指 Offer》内容


二、分析题目

解题思路(有较多解法):
  1. 定义三个指针,整体右移,边移动,边翻转,保证不会断链。
  2. 可以采用头插思想进行翻转。
  3. 递归递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?

    假设链表为:n_1→…→n_k−1→n_k→n_k+1→…→n_m→∅

    若从节点 n_k+1 到 n_m 已经被反转,而我们正处于 n_k 。

    n_1→…→n_k−1→n_k→n_k+1←…←n_m
    我们希望 n_k+1 的下一个节点指向 n_k。

    所以,n_k->next->next=n_k。

    需要注意的是 n_1 的下一个节点必须指向 ∅。如果忽略了这一点,链表中可能会产生环。


三、代码

1、方法一(三指针)

//牛客AC代码
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* ReverseList(ListNode* head) {
        if(head==nullptr || head->next==nullptr)
            return head;
        ListNode* left=head;
        ListNode* mid=head->next;
        ListNode* right=mid->next;
        while(right)
        {
            mid->next=left;
            left=mid;
            mid=right;
            right=right->next;
        }
        mid->next=left;
        head->next=nullptr;
        head=mid;
        return head;
    }
};

//力扣AC代码
/**
 * 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* reverseList(ListNode* head) {
        ListNode* cur=head;
        ListNode* prev=nullptr;
        while(cur)
        {
            ListNode* tmp=cur->next;
            cur->next=prev;
            prev=cur;
            cur=tmp;
        }
        return prev;
    }
};

2、方法二(插入)

//牛客AC代码
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* ReverseList(ListNode* head) {
        if(head==nullptr || head->next==nullptr)
            return head;
        ListNode* newHead=nullptr;
        while(head)
        {
            ListNode* p=head;
            head=head->next;
            p->next=newHead;
            newHead=p;
        }
        return newHead;
    }
};

//力扣AC代码
/**
 * 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* reverseList(ListNode* head) {
        if(head==nullptr || head->next==nullptr) return head;
        ListNode* newHead=nullptr;
        while(head)
        {
            ListNode* p=head;
            head=head->next;
            p->next=newHead;
            newHead=p;
        }
        return newHead;
    }
};

3、扩展:方法三(递归) 

//力扣AC代码(推荐:写法一)
/**
 * 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* reverseList(ListNode* head) {
        if(head==nullptr || head->next==nullptr) return head;
        ListNode* newHead=reverseList(head->next);
        head->next->next=head;
        head->next=nullptr;
        return newHead;
    }
};

//力扣AC代码(写法二)
/**
 * 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* reverse(ListNode* prev, ListNode* cur)
    {
        if(cur==nullptr) return prev;
        ListNode* tmp=cur->next;
        cur->next=prev;
        return reverse(cur, tmp);
    }
    ListNode* reverseList(ListNode* head) {
        return reverse(nullptr, head);
    }
};

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

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

相关文章

CoPilot 产品体验:提升 OpenNJet 的控制管理和服务提供能力

文章目录 前言系统架构介绍CoPilot 配置CoPilot 插件规范 体验 CoPilot 实例CoPilot: Broker 实例CoPilot: Ctrl 实例 开发其他语言编写的 CoPilot目标主要思路具体实现执行 go 程序代码 功能扩展总结 前言 CoPilot 是 OpenNJet 的一个重要组成部分,它在 Master-Wo…

【QA】Java常见运算符

前言 本文主要讲述Java常见的运算符 运算符的概念 两个基本概念: 运算符:对字面量或者变量进行操作的符号 表达式:用运算符把字面量或者变量连接起来符合java语法的式子就可以称为表达式 示例: int a 10; int b 20; int …

【一看就懂】UART、IIC、SPI、CAN四种通讯协议对比介绍

UART、IIC、SPI、CAN四种通信协议对比 通信方式传输线通讯方式标准传输速度使用场景UARTTX(发送数据线)、RX(接收数据线)串行、异步、全双工115.2 kbit/s(常用)计算机和外部设备通信(打印机)IICSCL(时钟线)、SDA(数据线)串行、同步、半双工100 kbit/s(标…

HNU-人工智能-实验4-基于Resnet的分类器

前言 本实验是自选实验,可以在给定范围内选择。 我刚刚提交了实验报告,暂时不准备放出我自己的实验报告,大概在截止提交之后我再放。 之所以这么着急写blog,是想便利还没做实验的同学。 如果选择的也是这个“毒蘑菇识别”的分类器…

安卓手机录屏在哪里?教给你3种方法

随着智能手机的普及,录屏功能在日常生活和工作中的需求日益增加。那么安卓手机录屏功能在哪里? 本文将详细介绍3个安卓手机的录屏方法,并分享一些实用技巧,帮助您更好地利用这一功能。 方法一:使用安卓手机自带的录屏…

武汉星起航:自运营团队—亚马逊平台运营典范,优势凸显业绩斐然

武汉星起航电子商务有限公司,作为跨境电商领域的佼佼者,凭借自运营团队多年的深耕经验与对亚马逊市场规则的深刻理解,成功在亚马逊平台开设多家自营店铺,并取得显著成绩。公司月流水达到几百万的辉煌业绩,不仅彰显了其…

基于 OpenHarmony compress 三方件使用指南~

关于 提供了一个轻量级的图像压缩库。将允许您将大照片压缩成小 尺寸的照片,图像质量损失或可以忽略不计 compress 的依赖添加 为你的应用添加 compress-debug.har。将 compress-debug.har 复制到 entry\libs 目录下即可(由于 build.gradle 中已经依赖…

笔记---DFS,深度优先搜索

深度优先搜索乃是注重深度,会把一条路径优先全部搜完然后再去回溯,再去搜其他路径 连通性模型 与BFS中的Flood Fill相似 AcWing.1112.迷宫 一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 n∗n 的格点组成&#xff…

Java:内存模型

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、Java内存模型出现的背景 二、什么是Java内存模型 三、Java内存模型的底层实现 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一…

基于C语言的贪吃蛇小游戏(简易版)

这篇博客会是对学习C语言成果的检测,为了实现贪吃蛇小游戏,我们用到的“工具”有:C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。 目录 1.简易版游戏效果 1.1欢迎界面 1.2游戏规则提示页面 1.3游戏进行页面 …

STM32F407VET6 学习笔记1:GPIO引脚认识分类与开发板原理图

今日学习STM32F407VET6 ,首先从基本原理图、引脚方面开始做个初步理解并整理: 这里使用的学习开发板是在嘉立创购买的 立创梁山派天空星,芯片是 STM32F407VET6 主要对这个芯片的引脚做一些归纳认识、对开发学习板原理图设计进行认识理解:最…

恭喜发财!东方第一 MEME 拥抱符文

第 431 号符文 HOPE•YOU•GET•RICH 🧧,是 Omnity 首个支持的跨链 Runes 资产,也是TG群里红包小程序支持的第一个 Runes 资产。 大家可以在 Omnity 的 TG 群和 RunesCC 的 TG 群里,不定时的抢到符文红包。 Omnity TG:…

智慧监测IN!计讯物联筑牢高速滑坡预警“安全锁”

在现代社会,高速公路以其高速、便捷的特性,早已成为连接城市与地区之间的重要纽带,承载着日益增长的车流和人流。然而,随着车流量的激增,高速公路面临的运营压力和安全挑战也随之加大,其中滑坡风险尤为突出…

ArrayList线程安全问题解决方案

jdk8 Stream API的出现大大简化了我们对于集合元素的处理代码,对于串行流来说,无需考虑线程安全问题;但是,对于并行流来说,由于它是以多线程的方式并行处理同一个集合中的数据元素的,因此,存在着…

智慧交通系统:未来出行,从这里开始

随着城市化进程的加快,交通拥堵、事故频发、停车难等问题日益凸显,传统交通管理模式已难以满足现代社会的需求。智慧交通系统作为解决这些问题的关键,通过集成创新技术,实现交通管理的智能化、信息化,提高交通系统的运…

Unity射击游戏开发教程:(10)创建主界面

主界面开发 玩游戏时,主菜单是事后才想到要做的。实际上几乎每个游戏都有一个主界面。如果你点击打开游戏并立即开始游戏,你会感到非常惊讶。本文将讨论如何创建带有启动新游戏的交互式按钮的主界面/主菜单。 主菜单将是一个全新的场景。我们将添加一个 UI 图像元素,并在图像…

洗地机什么牌子最好?618高性价比家用洗地机品牌

随着科技的发展,智能智能清洁家电越来越受到消费者的欢迎。洗地机作为其中的佼佼者,已经成为许多家庭清洁的好帮手。然而,面对满目琳琅的洗地机品牌型号,究竟哪一款机型适合家用呢,正好618也临近了,又有哪些…

C++笔记之调用PCL库显示PCD文件的点云

C++笔记之调用PCL库显示PCD文件的点云 —— 2024-05-05 杭州 code review! 文章目录 C++笔记之调用PCL库显示PCD文件的点云1.运行2.点云pcd文件github下载地址2.main.cpp3.CMakeLists.txt1.运行 2.点云pcd文件github下载地址 https://github.com/luolaihua/point-cloud-data-…

5.7代码

1.环境治理 分析:最开始进入了一个误区,觉得都有通路了直接算通路就可以,后来才发现居然是最小路径的总和,所以大概是每减一次都要算一次各点之间的最小路径了,然后是循环,到需要的条件为止 总的来说思路不…

通过颜色学习css

文章目录 1.生成html2.添加css链接3.将h1标签text-align元素4.添加div标签4.1、为类marker添加元素4.2、添加两个新的div标签4.3、修改div标签的类型并修改css元素4.4、为类container添加元素4.5、以数字形式添加颜色4.5、container添加padding属性4.6、组合css中的颜色属性4.7…