LeetCode Java刷题笔记—92. 反转链表 II
Posted 刘Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Java刷题笔记—92. 反转链表 II相关的知识,希望对你有一定的参考价值。
反转从位置 left 到 right 的链表,返回反转后的链表头节点。需要使用一趟扫描完成反转。
这道题相比于206题,难度加大,206题可以看做是此题的特例,即left=1,right=length。
因此,对于这道题,我们要先找到需要进行反转的位置,然后进行部分反转。
/**
* 92. 反转链表 II
* 反转从位置 left 到 right 的链表,返回反转后的链表头节点。需要使用一趟扫描完成反转。
* https://leetcode-cn.com/problems/reverse-linked-list-ii/
* 中等
*/
public class LeetCode92
/**
* 指针
*
* @param head
* @param left
* @param right
* @return
*/
public ListNode reverseBetween( ListNode head, int left, int right )
//由于head节点可能被交换位置,因此需要哨兵节点
ListNode dummy = new ListNode( 0, head );
ListNode pre = dummy;
//pre指向需要反转的链表部分的首节点的前驱
for( int i = 1; i < left; ++i )
pre = pre.next;
// head指向当前需要反转的链表节点
head = pre.next;
//开始反转,每次需要改变三个节点的引用关系,同时已经反转了的节点的关系不变
for( int i = left; i < right; ++i )
//获取当前需要反转的节点的后继
ListNode next = head.next;
//当前节点的后继指向后继节点的后继
head.next = next.next;
//后继节点的后继指向前驱节点的后继
next.next = pre.next;
//前驱节点的后继指向当前节点的后继,完成反转
pre.next = next;
return dummy.next;
public class ListNode
int val;
ListNode next;
ListNode()
ListNode( int val )
this.val = val;
ListNode( int val, ListNode next )
this.val = val;
this.next = next;
我们采用上面的算法,假设链表数据为1、2、3、4、5,left=2,right=4,下面是算法流程图。
当我们找到需要进行反转的节点之后,在进行循环之前,数据结构以及变量的关系如下:
进入循环体,开始第一次反转。首先计算出next = head.next。
然后我们需要将head和head.next进行反转,但是这两个节点之前和之后的引用必须保持不变。
我们首先设head.next = next.next,这样head节点就是next节点之后的链表关联起来了。
然后设next.next = pre.next,这样head和next节点的引用就反转了。
最后我们还需要设pre.next = next,next节点作为pre节点的新后继,这样反转的节点和之前的链表节点也关联起来了。
这样一轮循环就结束了,看起来很乱,我们调整一下顺序。
是不是一下就明白了,我们发现,2和3节点已经交换了,同时它们之前和之后的节点关系也没有改变。
下面开始第二轮循环。首先计算出next = head.next。
进行head.next = next.next,next.next = pre.next,pre.next = next操作。
这样第二轮循环就结束了,看起来很乱,我们调整一下顺序。
到此,进行了两轮循环,此时不满足循环条件,退出循环。我们发现此时已经完成了反转,注意我们需要返回dummy.next。
我们还可以发现,在循环过程中,pre和head始终指向同一个节点,这是不变的,改变的只是这些节点的next的指向,这就是这个循环的精妙之处。
以上是关于LeetCode Java刷题笔记—92. 反转链表 II的主要内容,如果未能解决你的问题,请参考以下文章