Leetcode 206 反转链表

反转链表

      • 准备工作
        • 1)ListNode基本结构
        • 2)初始化ListNode集合
      • 解法一:遍历创建新节点
      • 解法二:两组List,面向对象操作
      • 解法三:递归调用
      • 解法四:直接移动
      • 解法五:解法二的面向过程

Leetcode 206 反转链表

准备工作

1)ListNode基本结构
public class ListNode {public int val;public ListNode next;public ListNode(int val, ListNode next) {this.val = val;this.next = next;}@Overridepublic String toString() {ListNode node = this;StringBuilder sb = new StringBuilder();while (node != null) {sb.append(node.val).append("->");node = node.next;}sb.append("NULL");return sb.toString();}
}
2)初始化ListNode集合
public class ListNodeInit {public static ListNode getInitList() {ListNode tailf = new ListNode(5, null);ListNode node4 = new ListNode(4, tailf);ListNode node3 = new ListNode(3, node4);ListNode node2 = new ListNode(2, node3);return new ListNode(1, node2);}
}



解法一:遍历创建新节点

新增一个ListNode newList集合,然后直接遍历目标ListNode initList集合,每遍历一个节点就创建一个新节点,并且将新节点添加到我们newList中

public class 反转链表1 {public static void main(String[] args) {ListNode initList = ListNodeInit.getInitList();System.out.println(initList);System.out.println("-----反转后-----");System.out.println(reverseList(initList));}private static ListNode reverseList(ListNode initList) {ListNode newList = null;ListNode p = initList;// 遍历到原链表的节点while (p != null) {int val = p.val;// 创建一个新节点,新节点的下一个节点是之前的数据(将新值添加到头部)newList = new ListNode(val, newList);p = p.next;}return newList;}
}



解法二:两组List,面向对象操作

构建一个包装类List集合,用于封装addFirst、removeFirst方法,思路为移除oldList头部节点,然后添加到新的newList的头部

public class 反转链表2 {public static void main(String[] args) {ListNode initList = ListNodeInit.getInitList();System.out.println(initList);System.out.println("-----反转后-----");System.out.println(reverseList(initList));}private static ListNode reverseList(ListNode initList) {List oldList = new List(initList);List newList = new List(null);while (true) {// 原集合不停移除头部元素ListNode removedNode = oldList.removeFirst();if (removedNode == null) {break;}// 新集合不停添加到头部(类比栈)newList.addFirst(removedNode);}return newList.head;}static class List {ListNode head;public List(ListNode head) {this.head = head;}/*** 向头部添加节点*/public void addFirst(ListNode node) {node.next = head;head = node;}/*** 向尾部添加节点*/public ListNode removeFirst() {ListNode removedList = head;if (head != null) {head = head.next;}return removedList;}}
}



解法三:递归调用

利用递归后续遍历的回溯,能够反向拿到每一个元素的特点,不断的向initList尾部追加我们需要的逆序链表

public class 反转链表3 {public static void main(String[] args) {ListNode initList = ListNodeInit.getInitList();System.out.println(initList);System.out.println("-----反转后-----");System.out.println(reverseList(initList));}private static ListNode reverseList(ListNode initList) {if (initList == null || initList.next == null) {return initList;}// initList.next.val最多为5,因为5.next.val为null。即initList.val最多为4ListNode node = reverseList(initList.next);// 第一次调用时:// 5 -> 4,3,2,1  &&  4 -> null// 第二次调用时:// 4 -> 3,2,1    &&  3 -> null// 第三次调用时:// 3 -> 2,1      &&  2 -> null// 此处递归为后续遍历,可获取5,4,3,2,1顺序的值。// 步骤1)拿到node节点后,将当前node和其head部分分开,将node的head部分的上一个节点赋值到node的next,// 步骤2)且同时切断node和其head部分之间的关联//// 补充:前面提到initList.next.val最多为5,所以initList.next.next就是5的下一个节点initList.next.next = initList;initList.next = null;return node;}
}



解法四:直接移动

有点像选择排序,对两个元素进行互换位置,只不过此处为链表,难度大于数组。通过指针的关联关系,硬操作集合本身,每拿到一个节点,都将节点移动到头部

执行流程:

指针移动效果:

public class 反转链表4 {public static void main(String[] args) {ListNode initList = ListNodeInit.getInitList();System.out.println(initList);System.out.println("-----反转后-----");System.out.println(reverseList(initList));}private static ListNode reverseList(ListNode o1) {if (o1 == null || o1.next == null) {return o1;}// 1、设置o1、o2、n1三者之间的关系ListNode o2 = o1.next;ListNode n1 = o1;while (o2 != null) {// 2、断开o2节点:o1的下一个节点本来是指向o2,现在直接修改为指向o2的下一个节点,所以能够断开o1.next = o2.next;// 3、o2添加到头部:o2的下一个节点是n1节点,n1表示新节点的头部o2.next = n1;// 4、修正n1的位置:在赋初值的时候,n1代表头部节点,由于上一步头部添加一个一个o2,所以n1不是头部,此处重新指向到头部n1 = o2;// 5、修正o2的位置:由于前面o2节点执行到了头部,此处将o2节点重新指向下一个需要处理的节点,即o1的下一个o2 = o1.next;}return n1;}
}



解法五:解法二的面向过程

与解法二思想相同,解法二为面向对象,此处为面向过程;
与解法四的区别为此处将原来的List集合一分为二,移动节点位置本身,没有太大的区别

public class 反转链表5 {public static void main(String[] args) {ListNode initList = ListNodeInit.getInitList();System.out.println(initList);System.out.println("-----反转后-----");System.out.println(reverseList(initList));}private static ListNode reverseList(ListNode initList) {if (initList == null || initList.next == null) {return initList;}// 1、初始化o1、o2、n1三者之间的关系ListNode n1 = null;ListNode o1 = initList;ListNode o2 = null;while (o1 != null) {// 2、标记处理节点的下一个节点:用于标记剩余待处理节点的头节点o2 = o1.next;// 3、构建新list:o1表示要处理的节点,n1为初始化节点,此处将初始化节点和在处理的o1节点进行关联o1.next = n1;// 4、修正新list的头节点:经过上面的赋值,n1位置已经向后移动一个,此处调整n1 = o1;// 5、修正待处理list的头节点:经过上面的赋值,此时o1指向新集合的头部,此时借助前面的o2,将o1的位置修正为待处理list的头部o1 = o2;}return n1;}
}

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

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

相关文章

从c到c++——6:auto

在编写c程序时,需要在初始化变量时清楚地知道该变量的数据类型,有时这到这一点并不容易,在涉及到函数指针,多级指针时往往很难一下子给出准确的值。使用auto关键字很好的提高编程效率。 auto关键字会根据右边的类型自动生成适合的…

如何编写.gitignore文件

文章目录 前端架构师教你如何编写.gitignore文件.gitignore文件简介.gitignore文件的语法规则.gitignore文件的最佳实践常见问题与解决 前端架构师教你如何编写.gitignore文件 .gitignore文件简介 .gitignore文件是Git版本控制系统中一个非常有用的工具。它可以指定一组文件或…

Ubuntu 20.04 Server 使用命令行设置 IP 地址

1、编辑 /etc/netplan/ 目录下的配置文件00-installer-config.yaml (修改之前,把原来的文件备份) 按照对应的配置进行修改IP地址和网关 2、运行命令使其生效 sudo netplan apply 修改完成后,永久有效。重启后配置不会丢失

数据分析中需要用的的python知识(包括Numpy、Pandas、Matplotlib)

由于python的基础知识比较琐碎,这一块我打算以知识导图的形式呈现 软件:幕布 参考内容:菜菜菊花酱数据分析 python基础知识:https://www.mubu.com/doc/5uLBgn5LNTI numpy:https://www.mubu.com/doc/SgpdGGHMvI Pandas&…

2024年Java算法面试题

2024年Java实战面试题(北京)_java 5 年 面试-CSDN博客 一、波菲那契递归 System.out.println("banc " banc(10)) public static int banc(int n){if( n0 ){return 0;}else if( n1 ){return 1;}else{return banc(n-1) banc(n-2);} } 二、冒…

【智能家居入门之微信小程序控制下位机】(STM32、ONENET云平台、微信小程序、HTTP协议)

实现微信小程序控制单片机外设动作 一、使用ONENET可视化组件控制单片机外设动作二、使用微信小程序控制单片机外设动作三、总结 本篇博客话接上文: https://blog.csdn.net/m0_71523511/article/details/135892908 上一篇博客实现了微信小程序接收单片机上传的数据…

R语言【taxlist】——summary(),show(),print():打印taxlist对象及其内容的概述

Package taxlist version 0.2.4 Description 一种方法,用于显示 taxlist 对象内容的概述或所选分类组的概述。 Usage ## S4 method for signature taxlist summary(object,ConceptID,units "Kb",check_validity TRUE,display "both",maxs…

三、防御保护---防火墙安全策略篇

三、防御保护---防火墙安全策略篇 一、什么是安全策略二、安全策略的组成1.匹配条件2.动作3.策略标识 三、防火墙的状态检测和会话表1.会话表2.状态检测技术 四、ASPF--隐形通道五、用户认证1.用户认证的分类2.认证方式3.认证策略4.认证域 一、什么是安全策略 传统的包过滤防火…

Mysql 更新数据

MySQL中使用UPDATE语句更新表中的记录,可以更新特定的行或者同时更新所有的行。基本语法结构如下: UPDATE table_name SET column_name1 value1,column_name2 value2,……, column_namen valuen WHERE(condition); column_name1,column_name2,……,…

mcu专用看门狗复位芯片(如MAX706)

mcu专用看门狗复位芯片(如MAX706) 为什么要使用电压复位芯片RESET引脚WDO引脚MR引脚WDI引脚 国产替代型号应用电路1 推荐电路(用一个跳线帽使能/关闭看门狗功能,调试MCU时防止看门狗芯片随便触发复位功能),…

字符串函数自实现

1.strlen size_t strlen(const char *s);返回字符个数&#xff08;不包含结尾\0&#xff09; #include<stdio.h> #include<string.h>int mystr(const char* s) {int cnt 0;int index 0;while(s[index] ! \0){index;cnt;}return cnt; } int main() {char s[] &…

智能时代:自然语言生成SQL与知识图谱问答实战

语义解析 前言语义解析的应用场景总结概论语义解析和大模型的关系延伸阅读 前言 语义解析技术可以提高人机交互的效率和准确性&#xff0c;在自然语言处理、数据分析、智能客服、智能家居等领域都有广泛的应用前景。特别是在大数据时代&#xff0c;语义解析能够帮助企业更快速…

Unity中使用Ultraleap的InteractionButton组件

本节在上一节基础上进行&#xff0c;上一小结参考如下&#xff1a; Unity中创建Ultraleap 3Di交互项目 本节工程文件如下&#xff1a; Unity中使用Ultraleap的InteractionButton组件 本节结构有所更改&#xff0c;主要是参考官方示例结构进行重新调整&#xff0c;和上一小节相…

定时任务的corn表达式简要介绍

corn表达式的各项从左到右依次为&#xff1a;corn&#xff1a;秒 分钟 小时 日期 月份 星期几 年份 秒&#xff1a;0-59 分钟&#xff1a;0-59 小时&#xff1a;0-23 日期&#xff1a;1-31 月份&#xff1a;1-12 或 JAN-DEC 星期几&#xff1a;0-6 或 SUN-SAT 年份&#xff1a…

使用Process.Start()打开文件夹时出现访问被拒绝异常

默认的打开形式 Process.Start(folderPath); 解决方案 System.Diagnostics.Process.Start(Environment.GetEnvironmentVariable("WINDIR") "\explorer.exe", folderPath); 参考文献 c# - 使用 Process.Start() 打开文件夹时访问被拒绝异常 - IT工具网…

asp.net core接口报500错误排查

接口已经进行了try catch捕捉&#xff0c;但是还是报错&#xff0c;放到web.config下的错误&#xff0c;主要是是将stdoutLogEnabled修改为true <aspNetCore processPath"dotnet" arguments".\xxxx.dll" stdoutLogEnabled"true" stdoutLogFil…

·中介者模式

中介者模式 中介者模式 中介者模式 介绍&#xff1a;用一个中介对象来封装一系列的对象交互&#xff0c;中介者使各对象不需要显式地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间的交互。 实现&#xff1a;抽象中介者类&#xff0c;定义一个…

硬件知识(2) 手机的传感器-sensor

#灵感# 看看小米在干啥 手机型号&#xff1a;Redmi Note 13 Pro&#xff0c;解读一下它宣传的手机卖点。 目录 宣传1&#xff1a;1/1.4" 大底&#xff0c;f/1.65 大光圈&#xff0c; 宣传2&#xff1a;支持 2 亿像素超清直出&#xff0c;分辨率高达 16320 x 12240 宣…

Flutter CustomPainter 属性介绍与使用

Flutter 中的 CustomPainter 是一个强大的工具&#xff0c;允许开发者通过自定义绘制来创建各种复杂的图形和动画。本文将介绍 CustomPainter 的一些重要属性以及如何使用它们来实现自定义绘制。 1. CustomPainter 简介 CustomPainter 是一个抽象类&#xff0c;用于自定义绘制…

多态、多态的特点、类型转换(Java)

一、多态介绍 多态是在继承/实现情况下的一种现象&#xff0c;表现为&#xff1a;对象多态、行为多态。 对象多态就比如水果可以是苹果也可以是西瓜。 行为多态如何分辨呢&#xff0c;编译的时候会看People类中是否有run方法&#xff0c;运行的时候看Teacher中或者Student中的…