|
| 1 | +package com.codejayant.linkedList.inPlaceReversal; |
| 2 | + |
| 3 | +import com.codejayant.utils.ListNode; |
| 4 | + |
| 5 | +/** |
| 6 | + * Reverse a linked list from position m to n. Do it in one-pass. |
| 7 | + * <p> |
| 8 | + * Note: 1 ≤ m ≤ n ≤ length of list. |
| 9 | + * <p> |
| 10 | + * Example: |
| 11 | + * <p> |
| 12 | + * Input: 1->2->3->4->5->NULL, m = 2, n = 4 |
| 13 | + * Output: 1->4->3->2->5->NULL |
| 14 | + * |
| 15 | + * @see <a href="https://leetcode.com/problems/reverse-linked-list-ii/">LeetCode Problem</a> |
| 16 | + * @see <a href="https://www.educative.io/courses/grokking-the-coding-interview/qVANqMonoB2">Educative Problem</a> |
| 17 | + * @see <a href="https://leetcode.com/articles/reverse-linked-list-ii/">Article</a> |
| 18 | + */ |
| 19 | +public class ReverseSubList { |
| 20 | + |
| 21 | + /** |
| 22 | + * in-place iterative reversal of sub-list |
| 23 | + * T: O(n) |
| 24 | + * S: O(1) |
| 25 | + * |
| 26 | + * @param head root node |
| 27 | + * @param p start position of list to reverse |
| 28 | + * @param q end position of list to reverse |
| 29 | + * @return head of modified list |
| 30 | + */ |
| 31 | + private static ListNode reverse(ListNode head, int p, int q) { |
| 32 | + if (p == q) { |
| 33 | + return head; |
| 34 | + } |
| 35 | + |
| 36 | + // after skipping 'p-1' nodes, current will point to 'p'th node |
| 37 | + ListNode current = head, previous = null; |
| 38 | + for (int i = 0; current != null && i < p - 1; ++i) { |
| 39 | + previous = current; |
| 40 | + current = current.next; |
| 41 | + } |
| 42 | + |
| 43 | + // we are interested in three parts of the LinkedList, part before index 'p', part between 'p' and |
| 44 | + // 'q', and the part after index 'q' |
| 45 | + ListNode lastNodeOfFirstPart = previous; // points to the node at index 'p-1' |
| 46 | + // after reversing the LinkedList 'current' will become the last node of the sub-list |
| 47 | + ListNode lastNodeOfSubList = current; |
| 48 | + ListNode next; // will be used to temporarily store the next node |
| 49 | + // reverse nodes between 'p' and 'q' |
| 50 | + for (int i = 0; current != null && i < q - p + 1; i++) { |
| 51 | + next = current.next; |
| 52 | + current.next = previous; |
| 53 | + previous = current; |
| 54 | + current = next; |
| 55 | + } |
| 56 | + |
| 57 | + // connect with the first part |
| 58 | + if (lastNodeOfFirstPart != null) { |
| 59 | + lastNodeOfFirstPart.next = previous; // 'previous' is now the first node of the sub-list |
| 60 | + } else { // this means p == 1 i.e., we are changing the first node (head) of the LinkedList |
| 61 | + head = previous; |
| 62 | + } |
| 63 | + |
| 64 | + // connect with the last part |
| 65 | + if (lastNodeOfSubList != null) { |
| 66 | + lastNodeOfSubList.next = current; |
| 67 | + } |
| 68 | + |
| 69 | + return head; |
| 70 | + } |
| 71 | + |
| 72 | + public static void main(String[] args) { |
| 73 | + ListNode head = new ListNode(1); |
| 74 | + head.next = new ListNode(2); |
| 75 | + head.next.next = new ListNode(3); |
| 76 | + head.next.next.next = new ListNode(4); |
| 77 | + head.next.next.next.next = new ListNode(5); |
| 78 | + |
| 79 | + ListNode result = ReverseSubList.reverse(head, 2, 4); |
| 80 | + // expected value: 1 4 3 2 5 |
| 81 | + System.out.print("Nodes of the reversed LinkedList are: "); |
| 82 | + while (result != null) { |
| 83 | + System.out.print(result.val + " "); |
| 84 | + result = result.next; |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | +} |
0 commit comments