This problem is complex which has many edge cases so that it is not easy to write a bug free program within a short time. The idea of the solution is to go through the list, to the m, store the previous node before m, and start reversing from m to n. Then link the non-reversed and reversed part together.
/************************************************************************* > File Name: ReverseLinkedListII.java > Author: Yao Zhang > Mail: psyyz10@163.com > Created Time: Mon 16 Nov 14:48:56 2015 ************************************************************************/
publicclassReverseLinkedListII{ // Solution 1 publicstatic ListNode reverseBetween(ListNode head, int m, int n){ if (m>=n) return head; ListNode current = head; int i; ListNode startNode = null, newNode = null, previousNode = null; for (i = 1; i <= n; i++){ if (i == m - 1){ previousNode = current; } if (i == m){ startNode = newNode = current; } if (i>m){ ListNode temp = current.next; current.next = newNode; newNode = current; current = temp; continue; } current = current.next; } startNode.next = current; if (previousNode == null) head = newNode; else previousNode.next = newNode; return head; }
// Solution 2 public ListNode reverseBetween(ListNode head, int m, int n){ if (m >= n || head == null) return head; ListNode dummy = new ListNode(-1); dummy.next = head; ListNode prev = dummy; for (int i = 0; i < m - 1 ; i++){ if (prev == null) { return dummy.next; } prev = prev.next; } ListNode mPrev = prev; ListNode current = prev.next; ListNode last = new ListNode(current.val); ListNode first = last; current = current.next; for (int i = 0; i < n - m ; i++){ if (current == null) { return dummy.next; } ListNode temp = current.next; current.next = first; first = current; current = temp; } mPrev.next = first; last.next = current; return dummy.next; } }