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.
---
Solution: This is a tricky linked list question that is hard to get right the first time. The idea is quite straightforward. First, skip the first (m - 1) nodes so that you can get to one node before m. If m is the head node, then the node before head is called "beforeHead", which is an artificial node to simplify our algorithm.
Second, from the m-th node to the n-th node, reverse the list in-place.
Lastly, when the reversal is done, link up the whole list. You will need to join the node before m to the n-th node, and the m-th node to the node after n.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || m == n) return head;
// Avoid needing to keep track of head node later on.
ListNode beforeHead = new ListNode(0);
beforeHead.next = head;
// Skip first m-1 nodes to get to one node before m.
ListNode prev = beforeHead;
for (int i = m - 1; i > 0; i--) {
prev = prev.next;
}
// Reverse from nodes m to n in-place.
ListNode beforeMthNode = prev;
ListNode mthNode = prev.next;
ListNode cur = mthNode;
for (int i = n - m; i >= 0; i--) {
ListNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
// Tie up loose ends.
beforeMthNode.next = prev; // prev is the (n-1)-th node
mthNode.next = cur; // cur is the n-th node
return beforeHead.next;
}
}
No comments:
Post a Comment