leetcode LCR24反转单链表

反转单链表

题目描述

题目分析 

先来说迭代的思想:

上面next = cur->next应该放在cur->next = pre前面执行,这里笔误 

再来说递归的思想:

 题目代码

这个代码里面我加了我自己写的测试数据,自己可以去找对应的部分,直接粘贴赋值就可以在leetcode提交成功,我们就没有把迭代与递归单独分开了,里面还有大量的注释说明,请结合题目分析仔细观看

java版本

package com.pxx.test;import sun.awt.image.ImageWatched;class LinkList {private ListNode head;private int length;//长度//链表结点的一个定义static class ListNode {int value;ListNode next;//初始化一个结点public ListNode(int value) {this.value = value;this.next = null;}}public ListNode getHead() {return this.head;}//实现数据的尾插public void insertEnd(int value) {ListNode newNode = new ListNode(value);if (newNode != null) {if (head == null) {head = newNode;//指向第一个结点} else {ListNode cur = head;//移动到最后一个结点的位置while (cur.next != null) {cur = cur.next;}//最后一定是在cur加入结点cur.next = newNode;}length++;}}//打印public void printList(ListNode head) {ListNode cur = head;while (cur != null) {System.out.print(cur.value + " ");cur = cur.next;}System.out.println();}//利用递归反转链表//返回反转之后的链表头public ListNode reverse(ListNode head) {//安全检查都必须先进行操作if (head == null || head.next == null) {return head;} else {ListNode pre = head , cur = head.next;//接收最后一次的返回,就是最后一个节点,中间是没有结点要返回的//这里为什么传入pre.next,而不是cur.next//目的其实就是为了每一个值都能被链上,为什么那么说呢//1(pre) 2(cur) 3 4 5//如果按照cur.next来进行移动//1 <- 2这一部分递归了之后,就会进入 3(pre(cur会直接到3变成pre))   4(内部的cur)//那么我请问2 3中间这条线被狗吃了吗?所以以pre.next往下递归//上面pre循环到5号结点,也就是最后一组递归就要结束,因此有head.next = null就结束递归ListNode res = reverse(pre.next);cur.next = pre;//目的把第一个结点的next指向null//这里千万不能吧pre.next 与 cur.next进行比较//否则会造成最开头的两个数据一直轮替//这样来说 1  2  3  4(pre)  5(cur)假设当前指针是这样来指的//4 <- 5 此时4也还是4->5的,进入pre.next把指向变为了null(注意这是递归所以从后往前分析)//不太懂的请结合我的递归分析图来看//null <- 4 <- 5//那么就行往前递归3(pre) 4(cur) 5,也就是null <- 3 <- 4 <- 5//我们注意到一个问题就是4的pre已经在中间的时候被改向了第一个结点//那么对于1(pre) <- 2(cur)来说,1的.next又等于cur,所以1.pre = null//null <- 1 <- 2......这个时候,程序已经全部执行完if (pre.next == cur) {pre.next = null;}return res;}}//利用迭代思想实现public ListNode reverse1(ListNode head) {//空结点,直接返回一个nullif (head == null) {return null;}//定义三个指针进行迭代ListNode pre = head, cur = head.next, next;//next用于在中间轮替指针可以先不用初值//没循环之前先把第一个结点next指向nullhead.next = null;while (cur != null) {//这里迭代就是// null <- 1(pre) 2(cur) 3(next) 4        5// null <- 1 <-   2(pre) 3(cur)  4(next)  5// null <- 1 <-   2 <-   3(pre)  4(cur)   5(next)// null <- 1 <-   2 <-   3 <-    4(pre)   5(cur)   next(这个时候还会进入循环里面更改cur.next指针)//这个时候cur == null,结束,pre指向最后一个结点返回//保留next指向next = cur.next;//这一步必须放在cur.next前面,不然cur.next就被先改变了,next的位置就不对了cur.next = pre;//改变pre与curpre = cur;//这一步放在cur=next,这里就是先赋值pre,在改变curcur = next;}//最后一定是pre指向了最后一个结点return pre;}}public class Test4 {public static void main(String[] args) {LinkList linkList = new LinkList();//开始插入数据linkList.insertEnd(1);linkList.insertEnd(2);linkList.insertEnd(3);
//        linkList.insertEnd(4);
//        linkList.insertEnd(5);linkList.printList(linkList.getHead());//反转链表LinkList.ListNode head = linkList.reverse(linkList.getHead());linkList.printList(head);}
}

 c语言版本测试代码,仅做参考

#include <stdio.h>
#include <stdlib.h>// 链表结点的定义
struct ListNode {int value;struct ListNode* next;
};// 链表的定义
struct LinkedList {struct ListNode* head;int length;
};// 初始化链表
void initLinkedList(struct LinkedList* list) {list->head = NULL;list->length = 0;
}// 在链表末尾插入一个新节点
void insertEnd(struct LinkedList* list, int value) {struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));if (newNode != NULL) {newNode->value = value;newNode->next = NULL;if (list->head == NULL) {list->head = newNode;} else {struct ListNode* cur = list->head;while (cur->next != NULL) {cur = cur->next;}cur->next = newNode;}list->length++;}
}// 打印链表的元素
void printList(struct ListNode* head) {struct ListNode* cur = head;while (cur != NULL) {printf("%d ", cur->value);cur = cur->next;}printf("\n");
}// 递归反转链表
struct ListNode* reverse(struct ListNode* head) {if (head == NULL || head->next == NULL) {return head;} else {struct ListNode* pre = head;struct ListNode* cur = head->next;struct ListNode* res = reverse(pre->next);cur->next = pre;if (pre->next == cur) {pre->next = NULL;}return res;}
}int main() {struct LinkedList linkList;initLinkedList(&linkList);// 开始插入数据insertEnd(&linkList, 1);insertEnd(&linkList, 2);insertEnd(&linkList, 3);printList(linkList.head);// 反转链表linkList.head = reverse(linkList.head);printList(linkList.head);return 0;
}

好了,祝早安,午安,晚安

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

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

相关文章

【功能测试】软件系统测试报告

1.引言 1.1.目的 本测试报告为 xxx 系统测试报告&#xff0c;本报告目的在于总结测试阶段的测试及测试结果分析&#xff0c;描述系统是否达到需求的目的。 本报告预期参考人员包括测试人员、测试部门经理、开发人员、项目管理人员等。 1.2.参考文档 《xxxx系统需求规格说明…

Java线程安全问题

什么是线程安全问题 用程序模拟线程安全问题 主线程 package com.itheima.d3;public class ThreadTest {public static void main(String[] args) {//1、创建一个账户对象&#xff0c;代表两个人的共享账户Accout acc new Accout("ICBC-110",100000);//2、创建两个…

Django回顾【二】

目录 一、Web框架 二、WSGI协议 三、 Django框架 1、MVC与MTV模型 2、Django的下载与使用 补充 3、启动django项目 补充 5、 Django请求生命周期 四、路由控制 1、路由是什么&#xff1f; 2、如何使用 3、path详细使用 4、re_path详细使用 5、反向解析 6、路由…

Linux 中的 ls 命令使用教程

目录 前言 如何运用 ls 命令 1、列出带有所有权的文件和目录 2、获取以人类可读的方式显示的信息 3、列出隐藏文件 4、递归列出文件 5、在使用 ls 时对文件和目录做区分 6、列出指定扩展名的文件 7、基于大小对输出内容排序 8、根据日期和时间排序文件 让我们来总结…

从零带你底层实现unordered_map (2)

&#x1f4af; 博客内容&#xff1a;从零带你实现unordered_map &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准C后端工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家…

figma 基础使用 —— 常用方法

一、 导入组件 分成两种方式 &#xff08;1&#xff09;离线的包导入&#xff08;iOS 常用组件.fig 直接拖拽到figma最近网页&#xff09; &#xff08;2&#xff09;在插件市场下载https://www.figma.com/community 二、figma中使用标尺 快捷键&#xff1a;shift R 三、插…

宿主Linux——KVM安装Windows7系统

KVM虚拟技术 KVM(Kernel-based Virtual Machine) 是基于Linux内核的开源虚拟化技术&#xff0c;在一台物理机上可同时运行多个虚拟系统。KVM使用硬件虚拟化扩展&#xff0c;例如Intel的VT和AMD的AMD-V&#xff0c;在性能方面更加高效&#xff0c;可提供更好的计算能力和响应速…

【从浅识到熟知Linux】基本指令之rmdir和rm

&#x1f388;归属专栏&#xff1a;从浅学到熟知Linux &#x1f697;个人主页&#xff1a;Jammingpro &#x1f41f;每日一句&#xff1a;加油努力&#xff0c;这次写完真的真的真的要去干饭了&#xff01; 文章前言&#xff1a;本文介绍rmdir和rm指令用法并给出示例和截图。 文…

存在即合理,低代码的探索之路

目录 一、前言 二、低代码迅速流行的原因 三、稳定性和生产率的最佳实践 四、程序员用低代码开发应用有哪些益处&#xff1f; 1、提升开发价值 2、利于团队升级 一、前言 低代码的热潮至今未消停&#xff0c;从阿里钉钉跨平台协作方式&#xff0c;再到飞书上的审批流程&#xf…

房屋租赁出售经纪人入驻小程序平台

一款专为房屋中介开发的小程序平台&#xff0c;支持独立部署&#xff0c;源码交付&#xff0c;数据安全无忧。 核心功能&#xff1a;房屋出租、经纪人独立后台、分佣后台、楼盘展示、房型展示、在线咨询、地址位置配套设施展示。 程序已被很多房屋交易中介体验使用过&#x…

uni-app 离线打包安卓Apk(小白上手)

场景&#xff1a; 在使用uni-app 开发apk时&#xff0c;使用云打包有次数限制。尤其对于测试阶段是无比难受的&#xff0c;通常是浪费打包次数进行打包或者通过usb 给测试机更新开发环境&#xff0c;但这都是无比漫长的过程 尤其有多个测试机真的是噩梦般的存在 下载离线打包示…

【数据库】聊聊一颗B+树 可以存储多少数据

我们知道数据库使用的数据结构是B树&#xff0c;但是B树可以存储多少数据呢&#xff0c;在面试中也是经常会问的问题&#xff0c;所以我们从根上理解这个问题。 操作系统层面 数据都是存储在磁盘中的&#xff0c;而磁盘中的数据都是以最新单位扇区进行分割。一个扇区的大小是…

Python基础语法之学习数据转换

Python基础语法之学习数据转换 一、代码二、效果 一、代码 #数字转换成字符串 num_str str(11) print(type(num_str))#字符串转整数 numint("11") print(type(num),num)#浮点数转整数 float_num int(11.1) print(type(float_num),float_num)#整数转浮点数 num_flo…

OpenSSL 使用AES对文件加解密

AES&#xff08;Advanced Encryption Standard&#xff09;是一种对称加密算法&#xff0c;它是目前广泛使用的加密算法之一。AES算法是由美国国家标准与技术研究院&#xff08;NIST&#xff09;于2001年发布的&#xff0c;它取代了原先的DES&#xff08;Data Encryption Stand…

webpack项目工程初始化

一、初始化项目 默认系统已经安装node //初始化 pnpm init//安装webpack pnpm i -D webpack webpack-cli 新建一个index.html的入口文件 新建一个src文件存放js代码&#xff0c;src里面新建一个index.js package.josn配置打包命令 {"name": "webpack-cs&q…

Linux下基于MPI的hello程序设计

Linux下基于MPI的hello程序设计 一、MPICH并行计算库安装实验环境部署创建SSH信任连接&#xff0c;实现免密钥互相连接node1安装MPICH 3.4配置NFS注意(一定要先看)环境测试 二、HELLO WORLD并行程序设计 一、MPICH并行计算库安装 在Linux环境下安装MPICH执行环境&#xff0c;配…

【浅尝C++】C++类的6大默认成员函数——构造、析构及拷贝构造函数

&#x1f388;归属专栏&#xff1a;浅尝C &#x1f697;个人主页&#xff1a;Jammingpro &#x1f41f;记录一句&#xff1a;好想摆烂&#xff0c;又好想学习~~ 文章前言&#xff1a;本篇文章简要介绍C类的构造函数、析构函数及拷贝构造函数&#xff0c;介绍每个小点时&#xf…

【Linux专题】http(s)代理

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等_厦门微思网络的博客-CSDN博客文章浏览阅读444次。风和日丽&#xff0c;小微给你送福利~如果你是小微的老粉&#xff0c;这里有一份粉丝福利待领取...如果你是新粉关注到了小微&am…

【objectarx.net】table问题2:添加table后,保存时出错

添加table后&#xff0c;保存时出现以上对话框。 原因&#xff1a; tb.TableStyle db.Tablestyle; 对于这句代码&#xff0c;tb所在的数据库和db不是同一个。

java反射和注解3-仿照retrofit组装接口参数

本片文章将用反射和注解仿照retrofit只需要传入一个带有给定注解的接口&#xff0c;通过调用接口就能直接将传入的数据和注解进行结合&#xff0c;生成对应参数 1&#xff0c;自定义注解 对字段的修饰 Retention(RetentionPolicy.RUNTIME) Target(ElementType.PARAMETER) pu…