|
1 | 1 | package com.fishercoder.solutions;
|
2 | 2 |
|
3 | 3 | import com.fishercoder.common.classes.ListNode;
|
4 |
| -import com.fishercoder.common.utils.CommonUtils; |
5 | 4 |
|
6 |
| -/**Reverse a linked list from position m to n. Do it in-place and in one-pass. |
7 |
| -
|
8 |
| - For example: |
9 |
| - Given 1->2->3->4->5->NULL, m = 2 and n = 4, |
10 |
| -
|
11 |
| - return 1->4->3->2->5->NULL. |
12 |
| -
|
13 |
| - Note: |
14 |
| - Given m, n satisfy the following condition: |
15 |
| - 1 ≤ m ≤ n ≤ length of list.*/ |
| 5 | +/** |
| 6 | + * 92. Reverse Linked List II |
| 7 | + * |
| 8 | + * Reverse a linked list from position m to n. Do it in-place and in one-pass. |
| 9 | + * |
| 10 | + * For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, |
| 11 | + * |
| 12 | + * return 1->4->3->2->5->NULL. |
| 13 | + * |
| 14 | + * Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list. |
| 15 | + */ |
16 | 16 | public class _92 {
|
17 | 17 |
|
18 |
| - // then I turned to Discuss and find this most upvoted solution: |
19 |
| - // https://discuss.leetcode.com/topic/8976/simple-java-solution-with-clear-explanation, it's |
20 |
| - // indeed concise, I knew there's such a solution there |
21 |
| - public ListNode reverseBetween_concise_version(ListNode head, int m, int n) { |
22 |
| - // use four nodes, pre, start, then, dummy |
23 |
| - // just reverse the nodes along the way |
24 |
| - ListNode dummy = new ListNode(-1); |
25 |
| - dummy.next = head; |
26 |
| - ListNode pre = dummy; |
27 |
| - for (int i = 0; i < m - 1; i++) { |
28 |
| - pre = pre.next; |
29 |
| - } |
30 |
| - |
31 |
| - ListNode start = pre.next;// start is the node prior to reversing, in the given example, |
32 |
| - // start is node with value 1 |
33 |
| - ListNode then = start.next;// then is the node that we'll start to reverse, in the given |
34 |
| - // example, it's 2 |
35 |
| - |
36 |
| - for (int i = 0; i < n - m; i++) { |
37 |
| - // pay special attention to this for loop, it's assigning then.next to start.next, it |
38 |
| - // didn't initialize a new node |
39 |
| - // this does exactly what I desired to do, but I just didn't figure out how to implement |
40 |
| - // it, thumbs up to the OP! |
41 |
| - start.next = then.next; |
42 |
| - then.next = pre.next; |
43 |
| - pre.next = then; |
44 |
| - then = start.next; |
45 |
| - } |
46 |
| - |
47 |
| - return dummy.next; |
48 |
| - } |
49 |
| - |
| 18 | + public static class Solution1 { |
| 19 | + /** credit: https://discuss.leetcode.com/topic/8976/simple-java-solution-with-clear-explanation */ |
50 | 20 | public ListNode reverseBetween(ListNode head, int m, int n) {
|
51 |
| - // find node at position m, let's call it "revHead" |
52 |
| - // set its previous node as "newRevHead", then start processing until we reach node at |
53 |
| - // position n |
54 |
| - ListNode newRevHead = null; |
55 |
| - ListNode revHead = head; |
56 |
| - ListNode pre = new ListNode(-1); |
57 |
| - pre.next = head; |
58 |
| - if (m > 1) { |
59 |
| - int mCnt = 1; |
60 |
| - while (mCnt++ < m) { |
61 |
| - newRevHead = revHead; |
62 |
| - revHead = revHead.next; |
63 |
| - } |
64 |
| - } |
65 |
| - ListNode nodePriorToM = newRevHead; |
66 |
| - |
67 |
| - // iteratively |
68 |
| - int nCnt = m; |
69 |
| - ListNode next = null; |
70 |
| - while (nCnt <= n) { |
71 |
| - next = revHead.next; |
72 |
| - revHead.next = newRevHead; |
73 |
| - newRevHead = revHead; |
74 |
| - revHead = next; |
75 |
| - nCnt++; |
76 |
| - } |
77 |
| - |
78 |
| - if (nCnt > n) { |
79 |
| - nCnt--; |
80 |
| - } |
81 |
| - // append next to the tail of the reversed part |
82 |
| - ListNode reversedPart = newRevHead; |
83 |
| - if (reversedPart != null) { |
84 |
| - while (nCnt > m) { |
85 |
| - reversedPart = reversedPart.next; |
86 |
| - nCnt--; |
87 |
| - } |
88 |
| - reversedPart.next = next; |
89 |
| - } |
90 |
| - |
91 |
| - // append the reversed part head to the node at position m-1 |
92 |
| - if (nodePriorToM != null) { |
93 |
| - nodePriorToM.next = newRevHead; |
94 |
| - } else { |
95 |
| - pre.next = newRevHead; |
96 |
| - } |
97 |
| - |
98 |
| - return pre.next; |
| 21 | + // use four nodes, pre, start, then, dummy |
| 22 | + // just reverse the nodes along the way |
| 23 | + ListNode dummy = new ListNode(-1); |
| 24 | + dummy.next = head; |
| 25 | + ListNode pre = dummy; |
| 26 | + for (int i = 0; i < m - 1; i++) { |
| 27 | + pre = pre.next; |
| 28 | + } |
| 29 | + |
| 30 | + ListNode start = pre.next;// start is the node prior to reversing, in the given example, |
| 31 | + // start is node with value 1 |
| 32 | + ListNode then = start.next;// then is the node that we'll start to reverse, in the given |
| 33 | + // example, it's 2 |
| 34 | + |
| 35 | + for (int i = 0; i < n - m; i++) { |
| 36 | + // pay special attention to this for loop, it's assigning then.next to start.next, it |
| 37 | + // didn't initialize a new node |
| 38 | + // this does exactly what I desired to do, but I just didn't figure out how to implement |
| 39 | + // it, thumbs up to the OP! |
| 40 | + start.next = then.next; |
| 41 | + then.next = pre.next; |
| 42 | + pre.next = then; |
| 43 | + then = start.next; |
| 44 | + } |
| 45 | + |
| 46 | + return dummy.next; |
99 | 47 | }
|
100 |
| - |
101 |
| - public static void main(String... strings) { |
102 |
| - _92 test = new _92(); |
103 |
| - // ListNode head = new ListNode(1); |
104 |
| - // head.next = new ListNode(2); |
105 |
| - // head.next.next = new ListNode(3); |
106 |
| - // head.next.next.next = new ListNode(4); |
107 |
| - // head.next.next.next.next = new ListNode(5); |
108 |
| - // int m = 2, n =4; |
109 |
| - |
110 |
| - // ListNode head = new ListNode(5); |
111 |
| - // int m = 1, n =1; |
112 |
| - |
113 |
| - ListNode head = new ListNode(3); |
114 |
| - head.next = new ListNode(5); |
115 |
| - int m = 1; |
116 |
| - int n = 2; |
117 |
| - |
118 |
| - CommonUtils.printList(head); |
119 |
| - ListNode result = test.reverseBetween(head, m, n); |
120 |
| - CommonUtils.printList(result); |
121 |
| - } |
122 |
| - |
| 48 | + } |
123 | 49 | }
|
0 commit comments