【数据结构和算法】反转链表

其他系列文章导航

Java基础合集
数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、题目描述

二、题解

2.1 方法一:迭代(双指针)

2.2 方法二:递归

三、代码

3.1 方法一:迭代(双指针)

3.2 方法二:递归

四、复杂度分析

4.1 方法一:迭代(双指针)

4.2 方法二:递归


前言

这是力扣的 206 题,难度为简单,解题方案有很多种,本文讲解我认为最奇妙的一种。

继续开始链表的模块了,这道题是一道非常好的队列的例题,很有代表性。


一、题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?


二、题解

因为进阶要求两种方法来解决这道题目,所以本文都讲解!

如下图所示,题目要求将链表反转。本文介绍迭代(双指针)、递归两种实现方法。

Picture1.png

2.1 方法一:迭代(双指针)

思路与算法:

假设链表为 1→2→3→∅,我们想要把它改成 ∅←1←2←3。

在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

2.2 方法二:递归

递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?

假设链表为:
n1→…→nk−1→nk→nk+1→…→nm→∅

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

n1→…→nk−1→nk→nk+1←…←nm

我们希望 nk+1的下一个节点指向 nk。

所以,nk.next.next=nk

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


三、代码

3.1 方法一:迭代(双指针)

Java版本:

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head, pre = null;
        while(cur != null) {
            ListNode tmp = cur.next; // 暂存后继节点 cur.next
            cur.next = pre;          // 修改 next 引用指向
            pre = cur;               // pre 暂存 cur
            cur = tmp;               // cur 访问下一节点
        }
        return pre;
    }
}

C++版本:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *cur = head, *pre = nullptr;
        while(cur != nullptr) {
            ListNode* tmp = cur->next; // 暂存后继节点 cur.next
            cur->next = pre;           // 修改 next 引用指向
            pre = cur;                 // pre 暂存 cur
            cur = tmp;                 // cur 访问下一节点
        }
        return pre;
    }
};

Python版本:

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        cur, pre = head, None
        while cur:
            tmp = cur.next # 暂存后继节点 cur.next
            cur.next = pre # 修改 next 引用指向
            pre = cur      # pre 暂存 cur
            cur = tmp      # cur 访问下一节点
        return pre

3.2 方法二:递归

Java版本:

 public ListNode reverseList(ListNode head) {
        return recur(head, null);
    }

    private ListNode recur(ListNode cur, ListNode pre) {
        if (cur == null) return pre;
        ListNode res = recur(cur.next, cur);
        cur.next = pre;
        return res;
    }

C++版本:

class ListNode {
public: 
    int val;
    ListNode* next;
};

ListNode* reverseList(ListNode* head) {
    ListNode* pre = nullptr;
    ListNode* cur = head;
    while (cur) {
        ListNode* next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }
    return pre;
}

Python版本:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverseList(head):
    def recur(cur, pre):
        if not cur:
            return pre
        res = recur(cur.next, cur)
        cur.next = pre
        return res

    return recur(head, None)

四、复杂度分析

4.1 方法一:迭代(双指针)

  • 时间复杂度 O(N) : 遍历链表使用线性大小时间。
  • 空间复杂度 O(1) : 变量 pre 和 cur 使用常数大小额外空间。

4.2 方法二:递归

  • 时间复杂度 O(N) : 遍历链表使用线性大小时间。
  • 空间复杂度 O(N) : 遍历链表的递归深度达到 N ,系统使用 O(N) 大小额外空间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2018年认证杯SPSSPRO杯数学建模C题(第一阶段)机械零件加工过程中的位置识别全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 基于轮廓特征的机械零件位置识别研究 C题 机械零件加工过程中的位置识别 原题再现&#xff1a; 在工业制造自动生产线中&#xff0c;在装夹、包装等工序中需要根据图像处理利用计算机自动智能识别零件位置&#xff0c;并由机械手将零件自动搬…

云服务器CVM_云主机_弹性云计算服务器_腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

SQL Server中数据表的增删查改

文章目录 一、增二、查三、改四、删除 一、增 进行增删查改的前提需要在指定数据库中创建数据表&#xff0c;对这块不大理解的可以先看看前面几期文章&#xff1a; 创建数据库 创建数据表 use StudentManageDB go insert into Students (StudentName,Gender,Birthday,Age,Stu…

ImageNet Classification with Deep Convolutional 论文笔记

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

【QA】Linux-CentOS-全新虚拟机远程连接

文章目录 文章概述尝试连接问题1&#xff1a;解决拒绝连接的问题问题2&#xff1a;root用户可以远程连接了&#xff0c;其他用户不可以 文章概述 新安装的Linux-CentOS虚拟机进行远程连接&#xff0c;需要完成相关配置 尝试连接 虚拟机进入可视化页面&#xff0c;右键点击打…

【Docker】网络配置及自定义网络的使用

一、引言 1、什么是网络配置 Docker的网络配置主要是指Docker容器与外部网络之间的连接设置&#xff0c;包括容器内部的IP地址、端口号等。Docker提供了多种网络模式&#xff0c;包括bridge、host、none等&#xff0c;以满足不同的需求。 默认情况下&#xff0c;Docker使用brid…

android studio Connect timed out

Gradle Distributions 从上面的网站下载对应的版本 放到这个目录下

OpenCV——双边滤波

目录 一、双边滤波二、C代码三、python代码四、结果展示 OpenCV——双边滤波由CSDN点云侠原创。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫与GPT。 一、双边滤波 双边滤波是一种综合考虑滤波器内图像空域信息和滤波器内图像像素灰度值相似性的…

D2000 debian 11 arm64 aarch64 wine-ce编译安装,运行win32程序 笔记 【失败】

下载源码 yeqiangdebian:~/Downloads$ git clone https://gitee.com/wine-ce/wine-ce Cloning into wine-ce... remote: Enumerating objects: 102, done. remote: Counting objects: 100% (89/89), done. remote: Compressing objects: 100% (83/83), done. remote: Total 10…

【FastAPI】P1 简单实现 a+b

目录 准备工作代码运行 说明&#xff1a;本文通过 FastAPI 实现返回两个参数 ab 的值&#xff1b; 准备工作 默认读者已准备完善 Python IDE工具以及包管理工具。 首先&#xff0c;需要安装 fastapi 和 uvicorn 库&#xff0c;如果没有请使用 pip 进行安装&#xff1a; pip…

k8s的对外服务---ingress

service的作用体现在两个方面&#xff1a; 集群内部&#xff1a;不断追踪pod的变化。他会更新endpoint中的pod对象&#xff0c;基于pod的IP地址不断变化的一种服务发现机制。 集群外部&#xff1a;类似负载均衡器&#xff0c;把流量IP端口&#xff0c;不涉及转发url(http、htt…

电子雨html代码

废话不多说下面是代码&#xff1a; <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>Code</title><style>body{margin: 0;overflow: hidden;}</style></head><body><c…

react-app框架——使用monaco editor实现online编辑html代码编辑器

文章目录 ⭐前言&#x1f496;react系列文章 ⭐配置monaco-editor&#x1f496;引入react-monaco-editor&#x1f496;引入react-app-rewired&#x1f496;通过config-overrides.js添加monaco插件配置 ⭐编辑代码的react页面配置&#x1f496;扩展 可自定义配置语言 ⭐效果⭐总…

web开发学习笔记(8.java web后端开发基础知识)

1.使用spring开发的优势&#xff0c;spring发展到今天已经形成了一种开发生态圈&#xff0c;提供了若干个子项目&#xff0c;每个项目用于完成特定的功能。使用spring全家桶&#xff0c;可以做到很多事情&#xff0c;可以很方便的套用很多的组件。 2.pom构成 指定父工程 <p…

Java零基础教学文档第四篇:HTML_CSS_JavaScript(3)

**【JavaScript】 1.JavaScript的简介 1.1 JavaScript的诞生** 在1995年前后&#xff0c;当时世界上的主流带宽为28.8Kbps&#xff0c;现在世界平均下载带宽为21.9Mbps。当时的网民&#xff0c;每提交一次表单&#xff0c;都需要等待很久才能收到服务器的回应&#xff0c;甚至…

GPT-4 现在是否已经足够划算?

我通常使用 GPT 的方式是&#xff0c;先用 GPT-4 来快速搭建一个原型&#xff0c;然后不断优化&#xff0c;直到解决方案能够在 GPT-3.5 模型上运行。 这个方法在我的实践中非常高效&#xff0c;它的一个重要好处是能迅速筛选出那些“行不通”的项目——如果你在几天内都无法使…

循环异步调取接口使用数组promiseList保存,Promise.all(promiseList)获取不到数组内容,then()返回空数组

在使用 vue vant2.13.2 技术栈的项目中&#xff0c;因为上传文件的接口是单文件上传&#xff0c;当使用批量上传时&#xff0c;只能循环调取接口&#xff1b;然后有校验内容&#xff1a;需要所有文件上传成功后才能保存&#xff0c;在文件上传不成功时点击保存按钮&#xff0c…

HarmonyOS自学-Day5(使用List、Stack、RelativeContainer相关组件实现的小案例)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;小案例 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编程小白&#xff09;的 HarmonyOS自学笔记&#xff0c;此类文章笔记我会默认大家都学过前端相关的知识&#xff0c;并常常以实现相关小案例…

软考系分之计算机网络IP地址的表示(IPv4及IPv6)

文章目录 1、概要2、IPv4地址点分十进制和分类表示2.1 IPv4分类表示2.2 IPv4不分类表示2.3 IPv4特殊IP和子网划分 3、IPv6地址4、总结 1、概要 本篇介绍计算机网络中的IP地址&#xff0c;在网络工程师的考试中&#xff0c;IP地址是必考内容&#xff0c;但是在系统分析师的考察中…

Spring5.0 — WebClient(响应式web客户端)

一、介绍 1.1、RestTemplate 同步阻塞代码&#xff0c;http 请求返回响应才继续执行。 1.2、WebClient 1.基于 Reactor 和 Netty。 2.响应式 web 客户端。异步执行不阻塞代码&#xff0c;少量的线程数处理高并发的 Http 请求。 3.集成 Spring WebFlux 框架&#xff0c;可与…