leetcode题解-92. Reverse Linked List II

来源:互联网 发布:淘宝产品标题怎么写 编辑:程序博客网 时间:2024/05/16 12:44

题意:把链表中m到n的部分反转(1<=m<=n<=length)。
注意要求:在原地反转,也就是不能申请额外的空间,且只能遍历一遍。

例子:
链表 1->2->3->4->5->NULL, m = 2 and n = 4,
返回 1->4->3->2->5->NULL.

解析:
参考最高票的discuss,我们模拟一下逆置的过程:
1-2-3-4-5
先把3放2前面变成
1-3-2-4-5
再把4放3-2前面变成
1-4-3-2-5
循环该怎么做?

首先定义四个指针dummy,pre,start,then。
dummy为head的前置节点,只要题目可能涉及到头节点的变动,都需要声明dummy哑变量,最后返回dummy.next。
pre为一个不变的节点,用来标识在上述逆置过程中m的前置节点,在本题中为1。
start和then为用来逆置的节点,具体作用下面过程会有分析。

第一步,找到m的前置节点pre,然后start是pre的后继,then又是start的后继。在本题中pre为1节点,start为2节点,then为3节点。
第二部,利用pre,start,then这三个指针,从m+1到n的节点,依次放置到pre的后面。pre是永远不动的,因为插入的节点都需要插入它的后面,而start和then每次需要向后移动。即:

start.next = then.next;then.next = pre.next;pre.next = then;then = start.next;

那么本题的代码也就很容易写出来了:

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } */class Solution {   public ListNode reverseBetween(ListNode head, int m, int n) {        if(head == null) return null;        ListNode dummy = new ListNode(0);        dummy.next = head;        ListNode pre = dummy;        ListNode start = head;        ListNode then = head.next;        for(int i = 0; i < m - 1; i++){            pre = pre.next;            start = start.next;            then = then.next;        }        for(int i = 0; i < n - m; i++){            start.next = then.next;            then.next = pre.next;            pre.next = then;            then = start.next;        }        return dummy.next;    }}