Reverse Nodes in k-Group

一. Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example,

Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

Difficulty:Hard

TIME:35MIN

解法一(遞歸)

很多鏈表問題都可以採用遞歸來求解,這道題也不例外。每次遞歸的過程中,都對鏈表的前k個結點進行反轉,如果小於k個結點,就不反轉鏈表。

ListNode* reverseKGroup(ListNode* head, int k) {
    if(k <= 1)
        return head;
    ListNode *p = head;
    int num = 0;
    while(p != NULL && num != k) {
        p = p->next;
        num++;
    }
    if(num == k) {
        p = reverseKGroup(p, k); //這裏的p指向的是第k+1個結點
        while(num > 0) { //每次循環都將一個結點添加到p結點的前面
            ListNode *cur = head->next;
            head->next = p;
            p = head;
            head = cur;
            num--;
        }
        head = p; //這裏的p指向的是第1個結點
    }
    return head;
}

代碼的時間複雜度爲O(n)

解法二(迭代)

和遞歸方法類似,不過通過一些額外的變量保存了一些狀態信息。

ListNode* reverseKGroup(ListNode* head, int k) {
    if(k <= 1 || head == NULL)
        return head;
    ListNode *p = head;
    ListNode *end = head;  //指向k個結點已經反轉的尾結點(固定)
    ListNode *nex = end->next; //指向k個結點已經反轉的尾節點的下一個結點
    ListNode *result = new ListNode(-1);
    result->next = head;
    ListNode *pre = result; //指向k個結點已經反轉的首結點的前一個結點
    int num = 0;
    while(p != NULL) {
        p = p->next;
        num++;
    }
    while(num >= k) {
        end = pre->next;
        nex = end->next;
        for(int i = 1; i < k; i++) { //反轉至少需要3個結點的參與
            end->next = nex->next;
            nex->next = pre->next;
            pre->next = nex;
            nex = end->next;
        }
        pre = end;
        num -= k;
    }
    return result->next; //result一定會指向鏈表的首元素的前一個結點
}

代碼的時間複雜度爲O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章