题目:

给你单链表的头节点 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

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

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

本题与:剑指offer24.反转链表 一样

解题思路:

一、双指针(迭代)

设立两个指针节点,一个cur指向,初始指向head,一个pre,初始指向null,并设立一个临时节点temp用于保存cur的下一个节点,循环遍历链表,当cur为null时表示没有后续结点存在,停止循环,循环内做的事:

  • 保存cur的下一个结点,存在temp中:temp = cur.next;
  • 将当前cur的下一个指针指向pre:cur.next = pre;
  • pre向前移动一位:pre = cur;
  • cur向前移动一位:cur = temp

最后返回pre。

注意:为啥要先移动pre再移动cur,如果先先移动cur,cur = temp,pre的值再变为cur这时cur的值已经变了。

java代码:

 1 /**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode() {}
7 * ListNode(int val) { this.val = val; }
8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11 class Solution {
12 public ListNode reverseList(ListNode head) {
13 //申请两个指针,一个指向头结点一个指向空
14 ListNode cur = head;
15 ListNode pre = null;
16 //设置一个临时变量来保存cur的下一个结点
17 ListNode temp = null;
18 //当cur为空表示没有后续结点时停止循环
19 while(cur != null){
20 temp = cur.next;
21 cur.next = pre;
22 //将pre和cur前进一位
23 pre = cur;
24 cur = temp;
25 }
26 return pre;
27 }
28 }

 python3代码:

 1 # Definition for singly-linked list.
2 # class ListNode:
3 # def __init__(self, val=0, next=None):
4 # self.val = val
5 # self.next = next
6 class Solution:
7 def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
8 cur = head
9 pre = None
10
11 while cur:
12 temp = cur.next
13 cur.next = pre
14 pre = cur
15 cur = temp
16
17 return pre

 二、递归

递归看图解很好理解,但是看代码不是很好理解~ 参考@王尼玛大佬的题解和官方题解下各位大佬的注解

递归的两个条件:

  • 终止条件是当前节点或者下一个节点为null(head == null || head.next == null)
  • 在函数内部,改变节点的指向,即 head 的下一个节点指向 head :head.next.next = head

递归函数中每次返回的 cur 其实只是最后一个节点,在递归函数内部,改变的是当前节点的指向。

递归本质是栈,从尾部向前构造,这里出栈要做的事就是建立反向连接并删除正向连接。

举例:1-->2-->3-->4-->5

第一轮:首先一直递归,直到遇到5时,下一个结点为空了,就返回结点5,此时head = 5,head.next = null;

第二轮:head为4,head.next为5,执行head.next.next=head,即5.next = 4

  • 把当前节点的子节点的子节点指向当前节点,把5指向4;
  • 此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开,即4.next=null;
  • 此时链表为1->2->3->4<-5;
  • 返回节点5

第三轮出栈:head为3,head.next为4,执行head.next.next=head,即4.next =3

  • 把当前节点的子节点的子节点指向当前节点,把4指向3;
  • 此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开,即3.next=null;
  • 此时链表为1->2->3<-4<-5;
  • 返回节点5

第四轮出栈:head为2,head.next为3,执行head.next.next=head,即3.next =2

  • 把当前节点的子节点的子节点指向当前节点,把3指向2;
  • 此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开,即2.next=null;
  • 此时链表为1->2<-3<-4<-5;
  • 返回节点5

第五轮出栈:head为1,head.next为2,执行head.next.next=head,即2.next =1

  • 把当前节点的子节点的子节点指向当前节点,把2指向1;
  • 此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开,即1.next=null;
  • 此时链表为1<-2<-3<-4<-5;
  • 返回节点5

出栈完成,最终头结点5->4->3->2->1

注意:这里的newhead结点5,就相当于于从1楼爬上五楼拿了一个苹果,然后又从5楼下楼,每下一层楼就展示一下这个苹果。

 java代码:

 1 /**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode() {}
7 * ListNode(int val) { this.val = val; }
8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11 class Solution {
12 public ListNode reverseList(ListNode head) {
13 //设置终止条件
14 if(head == null || head.next == null) return head;
15 //递归传入下一结点,到达尾结点
16 ListNode newHead = reverseList(head.next);
17 head.next.next = head;
18 head.next = null;
19
20 return newHead;
21 }
22 }

python3代码:

 1 # Definition for singly-linked list.
2 # class ListNode:
3 # def __init__(self, val=0, next=None):
4 # self.val = val
5 # self.next = next
6 class Solution:
7 def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
8 if not head or not head.next:
9 return head
10
11 newHead = self.reverseList(head.next)
12
13 head.next.next = head
14 head.next = None
15
16 return newHead

2023-05-03日补充

递归(根据双指针的思路写出)

 1 //递归
2 class Solution {
3 public ListNode reverseList(ListNode head) {
4 if (head == null) return null;
5 return reverse(head, null);
6 }
7 public ListNode reverse(ListNode cur, ListNode pre){
8 if (cur == null) return pre;
9 ListNode temp = cur.next;
10 cur.next = pre;
11 return reverse(temp, cur);
12 }
13 }

栈:

 1 //使用栈
2 class Solution {
3 public ListNode reverseList(ListNode head) {
4 //处理特殊情况
5 if (head == null) return null;
6 if (head.next == null) return head;
7 //定义一个栈,让所有节点入栈
8 Stack<ListNode> stack = new Stack<>();
9 ListNode cur = head;
10 while (cur != null){
11 stack.push(cur);
12 cur = cur.next;
13 }
14 //出栈
15 //设置一个虚拟头结点
16 ListNode dummyHead = new ListNode(0);
17 cur = dummyHead;
18 while (!stack.isEmpty()){
19 ListNode node = stack.pop();
20 cur.next = node;
21 cur = cur.next;
22 }
23 cur.next = null;
24 return dummyHead.next;
25 }
26 }

力扣206(java&python)-反转链表(简单)的更多相关文章

  1. 力扣(LeetCode)反转链表 个人题解

    反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶:你可以迭代或 ...

  2. 力扣—Reorder List(重排链表)python实现

    题目描述: 中文: 给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→… 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点 ...

  3. 力扣——Partition List(分隔链表) python实现

    题目描述: 中文: 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = ...

  4. python反转字符串(简单方法)及简单的文件操作示例

    Python反转字符串的最简单方法是用切片: >>> a=' >>> print a[::-1] 654321 切片介绍:切片操作符中的第一个数(冒号之前)表示切片 ...

  5. 【力扣】82. 删除排序链表中的重复元素 II

    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字. 返回同样按升序排列的结果链表. 示例 1: 输入:hea ...

  6. LeetCoded第206题题解--反转链表

    反转一个单链表. 示例 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 方法一:递归 自始至 ...

  7. 力扣题目汇总(反转字符串中的单词,EXCEL表列序号,旋置矩阵)

    反转字符串中的单词 III 1.题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode ...

  8. 力扣(LeetCode)环形链表 个人题解

    给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. 示例 1: 输入: ...

  9. 力扣题解-面试题22. 链表中倒数第K个节点

    题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...

  10. 力扣 - 剑指 Offer 22. 链表中倒数第k个节点

    题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到栈(先进后出)里面,然后pop弹出k个元素就可以了 代码 class Solution ...

随机推荐

  1. GoFrame 优化接口的错误码和异常的思路

    前言 你是否想在使用 GoFrame 的过程中,拥有一个能打印异常堆栈,能自定义响应状态码,能统一处理响应数据的接口.如果你回答是,那么,请耐心看完本文,或许会对你有所启发.若文中由表达不当之处,恳请 ...

  2. springboot如何优雅的获取前端参数

    写在前面 对于初学者来说,困难的不是理论知识,而是如何在程序中具体实现. 现在的项目基本上都是前后端分离的项目,如何打通前后端,接收前端传过来的参数呢? 废话不多说,这篇文章就来说一说接收前端参数的具 ...

  3. JS(DOM事件高级)

    一 注册事件(绑定事件) 1.1 注册事件概述 给元素添加事件,称为注册事件或者绑定事件.注册事件有两种方式:传统方式和方法监听注册方式 1.2 addEventListener 事件监听方式 eve ...

  4. 三维模型3DTile格式轻量化在数据存储的重要性分析

    三维模型3DTile格式轻量化在数据存储的重要性分析 三维模型3DTile格式轻量化在数据存储中占有重要地位.随着科技的不断发展,尤其是空间信息科技的进步,人们对于三维地理空间数据的需求日益增长.然而 ...

  5. springboot 在 yaml 文件中读取 pom 文件的 properties

    如果没有其他配置,只能读取 yaml 文件所在模块下 和 父级模块的 pom 的 properties,以下是配置: <properties> <revision>1.0< ...

  6. 记录--7 个沙雕又带有陷阱的 JS 面试题

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 为了保证的可读性,本文采用意译而非直译. 在 JS 面试中,经常会看到一些简单而又沙雕的题目,这些题目包含一些陷阱,但这些在我们规范的编码 ...

  7. iOS模拟器 Unable to boot the Simulator —— Ficow笔记

    本文首发于 Ficow Shen's Blog,原文地址: iOS模拟器 Unable to boot the Simulator -- Ficow笔记. 内容概览 前言 终结模拟器进程 命令行改权限 ...

  8. 《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南 - 第5章

    本章勘误: 暂无,等待细心的你告诉我哦. 本章注解: 出处:207页 原文: 在我们的应用程序中,是不太可能出现LargeHeapHandleTable的问题的.一般来说,可能出现问题会是在需要(动态 ...

  9. EVENG导入Win7镜像以后可以启动无法VNC打开

    原因:未安装支持 eveng 的 vncviewer 解决方法:下载 vncviewer: https://pan.eve-ng.cn/Tools/EVE-NG/Client/EVE-NG-Win-C ...

  10. rsync 运维利器,同步工具

    NAME rsync - faster, flexible replacement for rcp SYNOPSIS rsync [OPTION]... SRC [SRC]... DEST rsync ...