1. 程式人生 > >[劍指offer]連結串列中倒數第k個結點/反轉連結串列/合併兩個排序的連結串列

[劍指offer]連結串列中倒數第k個結點/反轉連結串列/合併兩個排序的連結串列

題目描述

輸入一個連結串列,輸出該連結串列中倒數第k個結點。

解釋:

針對該道題目,主要有兩種解法:一種是將連結串列的節點壓入棧,由於棧有一個特點是先進後出,因此倒數第k個變成了順數第k個;第二種解法是求連結串列第k個節點,相當於順序遍歷連結串列第(n-k)個節點(計算下標從0開始),n為節點的總個數。其中對k的取值還要考慮,如果k的值大於連結串列總結點個數,則返回NULL。針對上述解釋的兩種解法,C++程式碼如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { //first solution stack<ListNode*>res; ListNode* ptemp = pListHead; int count = 0; while(ptemp!=NULL) { count++; res.push(ptemp); ptemp = ptemp->next; } ListNode *node = NULL; while
(k>=1 && k<=count) { node = res.top(); res.pop(); k--; } return node; //second solution ListNode*ptemp = pListHead; int count = 0; while(ptemp!=NULL) { count++; ptemp = ptemp->next; } if
(k==0) { return ptemp; } if(k==count) { return pListHead; } if(k>count) { return NULL; } else { int index = count - k; ListNode *temp = pListHead; while(index>0) { temp = temp->next; index--; } return temp; } } };

——————————————————————————————————————–

題目描述

輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。

解釋:

反轉連結串列也有兩種解法:第一種可以採用三個指標分別指向當前節點,當前節點的前一個節點和當前節點的後一個節點,具體反轉過程可檢視該連結;第二種解法是藉助vector容器,將連結串列節點的數值壓入容器中,然後再建立一個新連結串列,分別將反轉容器後的數值分別賦值給新連結串列節點值。C++程式碼如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) 
    {
//first solution
        if(pHead==NULL)
        {
            return NULL;
        }
        ListNode *p = pHead;
        ListNode *q = pHead->next;
        pHead->next = NULL;
        ListNode *r = NULL;
        while(q)
        {
            r = q->next;
            q->next = p;
            p = q;
            q = r;
        }
        pHead = p;
        return pHead;

// second solution
        vector<int>value;
        if(pHead==NULL)
        {
            return NULL;
        }
        ListNode *ptemp = pHead;
        while(ptemp!=NULL)
        {
            value.push_back(ptemp->val);
            ptemp = ptemp->next;
        }
        reverse(value.begin(),value.end());
        ListNode *head = new ListNode(value[0]);
        ListNode *temp = head;
        for(int i = 1;i<value.size();i++)
        {
            ListNode *node = new ListNode(value[i]);
            temp->next = node;
            temp = node;
        }
        return head;
    }
};

——————————————————————————————————————–

題目描述

輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。

解釋:

該題主要採用了遞迴,過程比較簡單,直接上程式碼:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1==NULL)
        {
            return pHead2;
        }
        if(pHead2==NULL)
        {
            return pHead1;
        }
        ListNode *head = NULL;
        if(pHead1->val<pHead2->val)
        {
            head = pHead1;
            head->next = Merge(pHead1->next, pHead2);
        }
        else
        {
            head = pHead2;
            head->next = Merge(pHead1, pHead2->next);
        }
        return head;
    }
};

——————————————————————————————————————–

歡迎大家給與意見!!!