问题描述
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list. 地址
问题分析
该题是LeetCode 206. Reverse Linked List 的进阶题,只要求反转某一部分链表 。 具体反转方法如下: 对于 1 -> 2 -> 3 -> 4 -> 5
, 如果要将它反转为 1 -> 4 -> 3 -> 2 -> 5
那么可以用preRevese
来指向待反转部分的前一个节点。用 curNode
c初始指向反转部分的第一个节点,然后将 curNode
的下一个节点 nextNode
换到 preReverse
的后面,用 curNode
来顶替他的位置。然后继续此过程,直至把 curNode0
移动至反转部分的尾部,便完成了反转
1 -> 2 -> 3 -> 4 -> 5
1 -> 3 -> 2 -> 4 -> 5
1 -> 4 -> 3 -> 2 -> 5
但是有一点需要注意,如果从头结点就开始反转怎么办?反转之后不久找不到头结点了嘛?
这就需要引入一个 dummy
节点,将原链表连在它的后面,这样既可原链表头结点发生改变,也能 通过 return dummy.next
的方式来返回调整后的整条链表。
经验教训
代码实现
public ListNode reverseBetween (ListNode head, int m, int n) {
if (head == null || head.next == null || m <= 0 || n <= 0 || m > n) {
return head;
}
ListNode curNode = head;
int length = 0 ;
while (curNode != null ) {
++length;
curNode = curNode.next;
}
if (n > length) {
return head;
}
ListNode dummy = new ListNode(0 );
dummy.next = head;
ListNode preReverse = dummy;
curNode = head;
for (int i = 1 ; i < m; i++) {
preReverse = curNode;
curNode = curNode.next;
}
for (int i = 1 ; i <= n - m; i++) {
ListNode nextNode = curNode.next;
curNode.next = nextNode.next;
nextNode.next = preReverse.next;
preReverse.next = nextNode;
}
return dummy.next;
}