1. 程式人生 > 其它 >連結串列中節點每k 個一組翻轉

連結串列中節點每k 個一組翻轉

技術標籤:C/C++面試連結串列節點翻轉

題目:

將給出的連結串列中的節點每k個一組翻轉,返回翻轉後的連結串列
如果連結串列中的節點數不是k的倍數,將最後剩下的節點保持原樣
你不能更改節點中的值,只能更改節點本身。
要求空間複雜度 O(1)

例如:

給定的連結串列是1→2→3→4→5

對於 k=2, 你應該返回 2→1→4→3→5

對於 k=3, 你應該返回 3→2→1→4→5

思路分析:

連結串列需要每k個就翻轉一次,那需要用到兩個函式進行兩次操作:

  • 一個是用來對連結串列進行分段,並確定最後一次是否滿足k個節點;
  • 一個是用來最小段連結串列進行翻轉,並將新的小段連結串列頭返回;

兩個操作可以分別用兩個函式封裝,也可以放到一個函式中。

方法一:可以先統計連結串列的長度,然後根據長度進行分段,再呼叫翻轉的功能

方法二:通過遞迴的方法,head記錄小段的頭,cur記錄下一個小段的起點,或是結束點的下一個節點。

因為翻轉的函式都一樣的,這裡只提供方法二的程式碼:

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int          value;
    struct node* next;
} list_node;



list_node* reverse(list_node* head, list_node* tail)
{
    list_node* pre  = NULL;
    list_node* next = NULL;

    while (head != tail) {
        next       = head->next;
        head->next = pre;
        pre        = head;
        head       = next;
    }

    return pre;
}

list_node* reverse_k_group(list_node* head, int k)
{
    list_node* cur      = head;
    list_node* new_head = NULL;

    for (int i = 0; i < k; ++i) {
        if (!cur) {
            return head;
        }

        cur = cur->next;
    }

    new_head   = reverse(head, cur);
    head->next = reverse_k_group(cur, k);

    return new_head;
}

void print(list_node* head, int k)
{
    list_node* cur = head;

    while (cur) {
        if (cur != head) {
            printf("->");
        } else {
            printf("k = %d:  ", k);
        }
        printf("%d", cur->value);

        cur = cur->next;
    }
    printf("\n");
}

void test10()
{
    list_node* head = NULL;
    list_node* cur  = NULL;

    for (int i = 0; i < 5; ++i) {
        list_node* node = (list_node*)malloc(sizeof(list_node));
        node->value     = i + 1;
        node->next      = NULL;

        if (!head) {
            head = node;
        }

        if (!cur) {
            cur = node;
        }
        else {
            cur->next = node;
            cur       = node;
        }
    }

    print(head, 1);

    head = reverse_k_group(head, 2);
    print(head, 2);
}
 

執行結果: