1. 程式人生 > >[LeetCode] Reverse Linked List II 倒置連結串列之二

[LeetCode] Reverse Linked List II 倒置連結串列之二

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->NULLm = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:
Given mn satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.

很奇怪為何沒有倒置連結串列之一,就來了這個倒置連結串列之二,不過猜也能猜得到之一就是單純的倒置整個連結串列,而這道作為延伸的地方就是倒置其中的某一小段。對於連結串列的問題,根據以往的經驗一般都是要建一個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的位置需要記下來,這樣我們就可以把倒置後的那一小段連結串列加入到原連結串列中。程式碼如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        ListNode *dummy = new ListNode(-1
); dummy->next = head; ListNode *cur = dummy; ListNode *pre, *front, *last; for (int i = 1; i <= m - 1; ++i) cur = cur->next; pre = cur; last = cur->next; for (int i = m; i <= n; ++i) { cur = pre->next; pre
->next = cur->next; cur->next = front; front = cur; } cur = pre->next; pre->next = front; last->next = cur; return dummy->next; } };