【LeetCode】一、链表反转

news2024/9/21 18:39:08

题目

题目:给定单链表头节点,将单链表的链接顺序反转过来
例:
输入:1->2->3->4->5
输出:5->4->3->2->1
要求:按照两种方式实现

解决办法

方式一:(直接迭代法)

思路

单链表的结构如下所示:
在这里插入图片描述
如图所示。我们分析一下,如果要完成翻转需要思考什么:

  1. 循环遍历所有节点,直到结束。所以需要确认结束条件
  2. 安全地将当前节点指向它的前驱节点(直接指向的话会导致链表遍历失败,如下所示,找不到下一个操作节点了)
    在这里插入图片描述

对于第1点,既然要循环遍历,那无非就是迭代器或者循环了,显然这里没办法使用迭代器,所以考虑使用while循环。何时结束呢?不难发现,就是【当前节点的next节点为null的时候】,或者我们新增一个节点currNode,表示当前操作节点,它随着遍历深度,不断往后移。显然它初始值是head头节点,所以可以使用currNode == null表示遍历结束了。
对于第2点,如何才能安全地将当前节点指向它的前驱节点呢?正常来说需要以下2步才能保证:

  1. 记录当前节点原有的next指向节点,这里记录为oldNextNode (原因见上图)
  2. 还需要一个前驱节点preNode记录下一个节点需要设置的前驱节点(也可以看上图,除了找不到next节点以外,其实next节点也找不到前面的节点了,所以也需要记录)

准备好了我们就可以尝试模拟了。
在这里插入图片描述
操作步骤:

  1. 设置oldNextNodecurrNode的next节点
  2. currNode的next节点指向preNode
  3. preNode设置为currNode
  4. currNode设置为oldNextNode
    在这里插入图片描述
    似乎没问题,那我们开始写代码吧

代码示例

代码如下:

public class ReverseLinkedList {
    public static void main(String[] args) {
        ListNode node5 = new ListNode(5, null);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);

        reverseLinkedList(node1);
    }

    private static void reverseLinkedList(ListNode head) {

        // 初始化我们的中间节点
        ListNode currNode = head;
        ListNode oldNextNode = null;
        ListNode preNode = null;

        // 循环遍历,currNode != null 则表示还没遍历到结尾
        while (currNode != null) {
            oldNextNode = currNode.next;
            currNode.next = preNode;
            preNode = currNode;
            currNode = oldNextNode;
        }

        System.out.println("试试看");
        System.out.println(preNode);
    }
}

最后我们看看结果吧:
在这里插入图片描述
倒过来了!

方式二:(递归法)

思路

(PS:既然说是递归解决了,那我们得先知道,递归能做什么。可以这么说,凡是能用递归解决的问题,一定是能将某个大问题,划分成N个存在共性的小问题。所以,我们可以朝这个方向看看。)

还是看着单链表的结构图来思考:
在这里插入图片描述
我们发现,如果从最后一个节点开始出发的话,这个题目的问题就会变成了另一个问题:我的前驱节点是谁?
在正常的遍历中,我们使用preNode状态节点来记录前驱节点,但在递归里面就没那么麻烦了!因为在正向递归遍历节点的时候,当前节点的结束,肯定是在前驱节点的调用处。效果图如下:
在这里插入图片描述
递归代码如下所示:

    public static void main(String[] args) {
        ListNode node5 = new ListNode(5, null);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);

//        reverseLinkedList(node1);
        recursion(node1);
    }

    private static ListNode recursion(ListNode curr) {

        // 递归出口(遍历到最后了)
        if (curr == null || curr.next == null) {
            return curr;
        }

        ListNode recursion = recursion(curr.next);
        System.out.println(recursion.value);
        return curr;
    }
//    系统输出:
//            5
//            4
//            3
//            2

既然知道了这个特点,我们只需要做如下步骤就好了:

  1. 每次递归调用,返回当前节点(这是为了创造当前节点能跟前驱节点在同一个代码块里的环境)
  2. 获得递归调用返回的节点recursion 之后,使用recursion .next = curr; curr.next = null;即可
    在这里插入图片描述

代码示例

   public static void main(String[] args) {
        ListNode node5 = new ListNode(5, null);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);

//        reverseLinkedList(node1);
        recursion(node1);
        System.out.println(node5);
    }

    private static ListNode recursion(ListNode curr) {

        // 递归出口(遍历到最后了)
        if (curr == null || curr.next == null) {
            return curr;
        }

        ListNode recursion = recursion(curr.next);
        recursion.next = curr;
        curr.next = null;
        return curr;
    }

最后我们看看结果吧:
在这里插入图片描述

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

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

相关文章

腾讯云服务器CVM镜像操作系统大全_win_linux

腾讯云CVM服务器的公共镜像是由腾讯云官方提供的镜像,公共镜像包含基础操作系统和腾讯云提供的初始化组件,公共镜像分为Windows和Linux两大类操作系统,如TencentOS Server、Windows Server、OpenCloudOS、CentOS Stream、CentOS、Ubuntu、Deb…

大一python编程题库和答案,大一python基础编程题库

大家好,小编来为大家解答以下问题,大一python编程题库和答案山东理工大学,大一python编程题库和答案解析,今天让我们一起来看看吧! 单项选择题 第一章python语法基础 1. Python 3.x 版本的保留字总数是C A 27 …

Python(五十七)列表生成式

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Delphi 开发不一样的窗体标题栏:TTitleBarPanel

目录 TTitleBarPanel 的使用 TTitleBarPanel 的使用进阶 一、设置标题栏高度、颜色 二、个性化标题栏的关闭等按键 我们在用Delphi开发程序的时候,窗体的标题栏一般都是标准的windows标题栏,上面包括:程序图标、标题、最小化、最大化、关闭…

TypeC拓展设计方案|TypeC转HDMI设计方案|CS5261/CS5265芯片设计参数对比

集睿智远CS5261/CS5265都可以用于设计TypeC转HDMI方案,低成本TypeC扩展坞设计方案,而两者也有些差异:1.CS5261支持DP1.4输入,一个HDMI1.4输出,即HDMI输出为4K30HZ ;CS5265DP1.4到HDMI2.0转换芯片,即HDMI输出…

Linux之 环境变量

什么是环境变量 windows中也有个 Linux 环境变量 env linux和windows环境变量,功能类似的, windows系统的环境变量,在cmd中可以之间调用程序运行。这些程序的执行程序的路径,一般编辑在path变量中 环境变量都分全局的&#xff…

Android性能优化—ANR问题分析

一、ANR是什么? ANR(Application Not responding),是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。可以简单的理解为应用…

网络入侵探测器Pi.Alert

什么是 Pi.Alert ? Pi.Alert 是 WIFI/LAN 入侵探测器。通过扫描连接到您的 WIFI/LAN 的设备,提醒您未知设备的连接。它还警告断开“始终连接”的设备。 Pi.Alert 使用了三种扫描方式 方式1:arp-scan。arp扫描系统实用程序用于使用 arp 帧搜索…

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 3

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…

CommunityToolkit.Mvvm8.1 viewmodel使用-旧式写法

0.说明 CommunityToolkit.Mvvm8.1有一个重大更新的功能:源生成器功能,它极大简化我们的mvvm代码 但是本篇先总结一下原写法,下篇再总结源生成器功能 1.模型定义 必须继承:ObservableObject 2.viewmodel代码实现 几个关键点: SetProperty是给属性赋值,并且通知更改通知 But…

钉钉对接打通金蝶云星空获取流程实例列表详情(宜搭)接口与其他应收单接口

钉钉对接打通金蝶云星空获取流程实例列表详情(宜搭)接口与其他应收单接口 对接系统钉钉 钉钉(DingTalk)是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台,提供PC版,Web版和手机版,有考…

Linux知识点 -- VS Code远程连接服务器协助开发

Linux知识点 – VS Code远程连接服务器协助开发 文章目录 Linux知识点 -- VS Code远程连接服务器协助开发一、VS Code的使用1.使用VS Code进行C语言编译与运行2.使用VS Code进行C代码的编译与运行 二、使用VS Code连接云服务器三、使用VS Code进行GDB调试 一、VS Code的使用 1…

Redis的基础知识

目录 一、什么是Redis 二、关于Redis的一些基本知识 (1)set命令 (2)get命令 三、Redis中的一些常用命令 (1)keys (2)exists (3)type (4…

vite+typescript项目 :找不到模块“./***.vue”或其相应的类型声明——解决方案

vue3ts报错&#xff1a; 找不到模块“./App.vue”或其相应的类型声明。ts(2307) 解决方法&#xff1a; 1、在src文件夹找到 vite-env.d.ts 加入以下代码&#xff1a; declare module *.vue {import type { DefineComponent } from vueconst vueComponent: DefineComponent<…

Nodejs 第六章(npx)

npx是什么 npx是一个命令行工具&#xff0c;它是npm 5.2.0版本中新增的功能。它允许用户在不安装全局包的情况下&#xff0c;运行已安装在本地项目中的包或者远程仓库中的包。 npx的作用是在命令行中运行node包中的可执行文件&#xff0c;而不需要全局安装这些包。这可以使开…

手机python编程软件怎么用,手机python编程软件下载

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;手机python编程软件保存的代码在哪里&#xff0c;手机python编程软件怎么运行&#xff0c;现在让我们一起来看看吧&#xff01; 原标题&#xff1a;盘点几个在手机上可以用来学习编程的软件 前天在悟空问答的时候&#…

win上打包发包发布

地址 192.168.X.X 账号密码 zhanghaomima 连接方式&#xff1a; Win自带工具&#xff1a; 远程桌面连接 更新客户端代码 直接替换 D:\xmes\client3\elements 下的 cust-bundles 文件夹 更新mobile代码 直接替换 D:\xmes\mobile\scripts 下的fragments文件夹 更新服务端代…

【物理】带电粒子在磁场和电场中移动的 3D 轨迹研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2023年华数杯建模思路 - 案例:粒子群算法

# 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法&#xff1f; 粒子群算法&#xff08;Particle Swarm Optimization,PSO&#xff09;是一种模仿鸟群、鱼群觅食行为发展起来的一种进化算…

基于元宇宙与 Web3 的虚拟世界:客户体验的颠覆与重生

随着科技的飞速发展&#xff0c;互联网已经逐渐融入了我们生活的方方面面。然而&#xff0c;传统的互联网体验在很多方面仍然存在局限性。客户需要花费大量时间和精力去实体店购买商品、在电商平台上筛选商品&#xff0c;或者在固定的时间和地点接受教育。这些问题在元宇宙与 W…