Medium!
題目描述:
反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。
說明:
1 ≤ m ≤ n ≤ 鏈表長度。
示例:
輸入: 1->2->3->4->5->NULL, m = 2, n = 4 輸出: 1->4->3->2->5->NULL
解題思路:
根據以往的經驗一般都是要建一個dummy node,連上原鏈表的頭結點,這樣的話就算頭結點變動了,我們還可以通過dummy->next來獲得新鏈表的頭結點。這道題的要求是只通過一次遍歷完成,就拿題目中的例子來說,變換的是2,3,4這三個點,那么我們可以先取出2,用front指針指向2,然后當取出3的時候,我們把3加到2的前面,把front指針前移到3,依次類推,到4后停止,這樣我們得到一個新鏈表4->3->2, front指針指向4。對於原鏈表連說,有兩個點的位置很重要,需要用指針記錄下來,分別是1和5,因為當2,3,4被取走時,原鏈表就變成了1->5->NULL,要把新鏈表插入的時候需要這兩個點的位置。1的位置很好找,因為知道m的值,我們用pre指針記錄1的位置,5的位置最后才能記錄,當4結點被取走后,5的位置需要記下來,這樣我們就可以把倒置后的那一小段鏈表加入到原鏈表中。
C++解法一:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *reverseBetween(ListNode *head, int m, int n) { 12 ListNode *dummy = new ListNode(-1); 13 dummy->next = head; 14 ListNode *cur = dummy; 15 ListNode *pre, *front, *last; 16 for (int i = 1; i <= m - 1; ++i) cur = cur->next; 17 pre = cur; 18 last = cur->next; 19 for (int i = m; i <= n; ++i) { 20 cur = pre->next; 21 pre->next = cur->next; 22 cur->next = front; 23 front = cur; 24 } 25 cur = pre->next; 26 pre->next = front; 27 last->next = cur; 28 return dummy->next; 29 } 30 };