【题目】
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.
题意:把链表中m到n的部分反转(1<=m<=n<=length)。
注意要求:在原地反转,也就是不能申请额外的空间,且只能遍历一遍。
自然而然想到把链表分为三部分,重点是如何遍历一遍把中间部分反转?借助两个指针,tmpHead和tmpNext,tmpHead是遍历反转后的head,tmpNext始终是tmpHead反转后的next。
直接看代码吧,代码中有注释,不懂的请留言。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
// Divide the list to three parts:
// 1)Nodes before m keep still;
// 2)Traverse m~n nodes;
// 3)Nodes after n keep still.
public ListNode reverseBetween(ListNode head, int m, int n) {
if (m == n) return head;
ListNode preHead = new ListNode(0);
preHead.next = head;
// The (m-1) node is the tail of first tail.
ListNode firstTail = preHead;
int k = m - 1;
while (k-- > 0) {
firstTail = firstTail.next;
}
// The m-th node is the traversed tail.
ListNode secondTail = firstTail.next;
// Traverse m~n nodes, and get the traversed head.
ListNode tmpHead = null;
ListNode tmpNext = null;
ListNode node = firstTail.next;
k = n - m + 1;
while (k-- > 0) {
tmpHead = node;
node = node.next;
tmpHead.next = tmpNext;
tmpNext = tmpHead;
}
// Connect three parts.
firstTail.next = tmpHead;
secondTail.next = node;
return preHead.next;
}
}
指针关系比较复杂,想清楚了在写代码。
相关题目: 【LeetCode】Reverse Nodes in k-Group 解题报告