C++ 鏈表題型

目錄

 

鏈表題目:

1.從尾到頭打印鏈表

2.鏈表的倒數第k個結點

3. 翻轉鏈表

4.合併2 個有序的鏈表

5. 兩個鏈表的第一個公共結點

6. 鏈表中環的入口

7. 刪除鏈表中重複的節點


鏈表題目:

1.從尾到頭打印鏈表

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        // 使用棧來保存
        if (head == nullptr) return vector<int>();
        stack<int> mystack;
        vector<int> res;
        ListNode* p = head;
        while (p != nullptr){
            mystack.push(p->val);
            p = p->next;
        }
        while (!mystack.empty()){
            res.push_back(mystack.top());
            mystack.pop();
        }
        return res;
        
    }
};

2.鏈表的倒數第k個結點

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        // 設置一個結點先走k步,然後一起走
        if (pListHead == nullptr) return NULL;
        if (k < 0) return NULL;
        ListNode* p = pListHead;
        for (int i = 0; i< k-1; i++){
            p = p->next;
            if (p == nullptr) return NULL;
        }
        while (p->next != nullptr){
            p = p->next;
            pListHead = pListHead->next;
        }
        return pListHead;
    
    }
};

3. 翻轉鏈表

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (pHead == nullptr || pHead-> next == nullptr) return pHead;
        ListNode* p = pHead;
        ListNode* newP = NULL;
        ListNode* temp = NULL;
        while (p){
            temp = p->next;
            p->next = newP;
            newP = p;
            p = temp;
        }
        return newP;
    
    }
};

遞歸的形式翻轉鏈表:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        // 使用遞歸的方法來翻轉一個鏈表
        if (pHead == nullptr || pHead->next == nullptr){
            return pHead;
        }
        ListNode* reversedP;
        reversedP = ReverseList(pHead->next);
        pHead->next->next = pHead;
        pHead->next = NULL;
        
        return reversedP;

    }
};

4.合併2 個有序的鏈表

/*
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 == nullptr && pHead2 != nullptr){
            return pHead2;
        }
        if (pHead2 == nullptr && pHead1 != nullptr){
            return pHead1;
        }
        
        if (pHead1 == nullptr && pHead2 == nullptr){
            return NULL;
        }
        ListNode* ret = NULL; // 先在外部進行聲明
        
        if (pHead1->val >= pHead2-> val){
            ret = pHead2;
            ret->next = Merge(pHead1, pHead2->next);
        }else{
            ret = pHead1;
            ret->next = Merge(pHead1->next, pHead2);
        }
        return ret;
        
        
        
    }
};

5. 兩個鏈表的第一個公共結點

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        // 先計算2 個鏈表的長度,然後計算差值k,短的先走k步,然後一起走,知道有相同的結點
        if (pHead1 == nullptr || pHead2 == nullptr){
            return NULL;
        }
        int len1= 0;
        int len2 = 0;
        ListNode* move1 = pHead1;
        ListNode* move2 = pHead2;
   
        while (move1 != nullptr){
            len1 ++;
            move1 = move1->next;
        }
        
        while (move2 != nullptr){
            len2++;
            move2 = move2->next;
        }
        
        while (len1 > len2){
            len1 --;
            pHead1 = pHead1->next;
        }
        
        while (len1 < len2){
            len2 --;
            pHead2 = pHead2->next;
        }
        // 一起往前走
        while (pHead1 != nullptr){
            if (pHead1 == pHead2){
                return pHead1;
            }else{
                pHead1 = pHead1->next;
                pHead2 = pHead2->next;
            }
        }
        
    }
};

6. 鏈表中環的入口

設置快慢結點,找到相遇的結點;然後首結點和相遇的節點一起往前走,直到找到相交的結點。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        // 設置快慢結點,走1 步和走2步,找到相遇的結點q; 然後q 和頭部結點一起往前走,直到找到相遇的結點;
        if (!pHead || !pHead->next || !pHead->next->next) return NULL;
        ListNode* low = pHead->next;
        ListNode* fast = pHead->next->next;
        while (low != fast){
            if (!low->next || !fast->next->next) return NULL;
            low = low->next;
            fast = fast->next->next;
        }
        
        while (fast != pHead){
            pHead = pHead->next;
            fast = fast->next;
        }
        return pHead;

    }
};

7. 刪除鏈表中重複的節點

重複的結點全部刪除

1. 設置dummy 結點; 2. 設置一個 前置結點last 和當前結點 pHead, 使用last -> next 指向pHead ,即刪除結點

3. 設置初始的判斷條件是  while (pHead && pHead -> next)

創建一個結點:  ListNode* node = new ListNode(-1);

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if (!pHead || !pHead->next) return pHead;
        // 創建一個dummy 結點
        ListNode* first = new ListNode(-1);
        first->next = pHead;
        ListNode* last = first;
        
        while(pHead && pHead->next){
            if (pHead->val == pHead->next->val){
                int values = pHead->val;
                while (pHead && pHead->val == values){
                    pHead = pHead->next;
                }
                last->next = pHead;
            }else{
                last = last->next;
                pHead = pHead->next;
            }
        }
        return first->next;

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