題目:
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.
題解:
經典的題目就是鏈表逆序啦,一般的鏈表逆序是讓把鏈表從前到后都逆序,這個是給定了起始位置和結束位置,方法是一樣的。
就是維護3個指針,startpoint,node1和node2。
startpoint永遠指向需要開始reverse的點的前一個位置。
node1指向正序中第一個需要rever的node,node2指向正序中第二個需要reverse的node。
交換后,node1 在后,node2在前。這樣整個鏈表就逆序好了。
代碼如下:
1
public ListNode reverseBetween(ListNode head,
int m,
int n) {
2 ListNode newhead = new ListNode(-1);
3 newhead.next = head;
4
5 if(head== null||head.next== null)
6 return newhead.next;
7
8 ListNode startpoint = newhead; // startpoint指向需要開始reverse的前一個
9 ListNode node1 = null; // 需要reverse到后面去的節點
10 ListNode node2 = null; // 需要reverse到前面去的節點
11
12 for ( int i = 0; i < n; i++) {
13 if (i < m-1){
14 startpoint = startpoint.next; // 找真正的startpoint
15 } else if (i == m-1) { // 開始第一輪
16 node1 = startpoint.next;
17 node2 = node1.next;
18 } else {
19 node1.next = node2.next; // node1交換到node2的后面
20 node2.next = startpoint.next; // node2交換到最開始
21 startpoint.next = node2; // node2作為新的點
22 node2 = node1.next; // node2回歸到node1的下一個,繼續遍歷
23 }
24 }
25 return newhead.next;
26 }
2 ListNode newhead = new ListNode(-1);
3 newhead.next = head;
4
5 if(head== null||head.next== null)
6 return newhead.next;
7
8 ListNode startpoint = newhead; // startpoint指向需要開始reverse的前一個
9 ListNode node1 = null; // 需要reverse到后面去的節點
10 ListNode node2 = null; // 需要reverse到前面去的節點
11
12 for ( int i = 0; i < n; i++) {
13 if (i < m-1){
14 startpoint = startpoint.next; // 找真正的startpoint
15 } else if (i == m-1) { // 開始第一輪
16 node1 = startpoint.next;
17 node2 = node1.next;
18 } else {
19 node1.next = node2.next; // node1交換到node2的后面
20 node2.next = startpoint.next; // node2交換到最開始
21 startpoint.next = node2; // node2作為新的點
22 node2 = node1.next; // node2回歸到node1的下一個,繼續遍歷
23 }
24 }
25 return newhead.next;
26 }