程式碼隨想錄訓練營第三天 | 203.移處連結串列元素 707.設計連結串列 206.反轉連結串列

深蓝von發表於2024-05-11

203.移除連結串列元素

題目連結 https://leetcode.cn/problems/remove-linked-list-elements/
文章講解 https://programmercarl.com/0203.移除連結串列元素.html#演算法公開課
影片講解 https://www.bilibili.com/video/BV18B4y1s7R9/?vd_source=2b5b33d3d692b0064daff4e58957fc82
tips:對於連結串列操作leetcode中都是預設不帶頭節點的連結串列,題目中的頭節點都是儲存資料的,這樣在移除元素的時候就需要根據是否是頭節點而進行不同的操作,大大增加了程式碼的複雜度;一般考慮初始化一個虛擬的頭節點來對連結串列進行操作;
刪除節點時注意釋放節點記憶體,避免記憶體洩漏

  • 時間複雜度 o(n)
  • 空間複雜度 o(1)
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 初始化一個虛擬頭節點
        ListNode * dummy_head = new ListNode{};
        dummy_head->next = head;
        ListNode * p = dummy_head;

        while(p->next != nullptr) {
            if(p->next->val == val) {
                ListNode * temp = p->next;
                p->next = p->next->next;
                delete temp;
            } else {
                p = p->next;
            }
        }
        // 最終虛擬頭節點的下一個節點就是所求連結串列的實際頭節點
        return dummy_head->next;
    }
};

707.設計連結串列

題目連結 https://leetcode.cn/problems/design-linked-list/
文章連結 https://programmercarl.com/0707.設計連結串列.html#演算法公開課
https://www.bilibili.com/video/BV1FU4y1X7WD/?vd_source=2b5b33d3d692b0064daff4e58957fc82

class MyLinkedList {
public:
public:
    struct listNode {
        int val;
        listNode * next;
        listNode(int _val): val(_val), next(nullptr) {}
    };
    MyLinkedList() {
        head = new listNode(0);
        size = 0;
    }
    
    int get(int index) {
        if (index >= size || index < 0) return -1;
        listNode * current = head->next;
        while(index--) {
            current = current->next;
        }
        return current->val;
    }
    
    void addAtHead(int val) {
        listNode * node = new listNode(val);
        node->next = head->next;
        head->next = node;
        ++size;
    }
    
    void addAtTail(int val) {
        listNode * current = head;
        while(current->next != nullptr) 
            current = current->next;
        current->next = new listNode(val);
        ++size;
    }
    
    void addAtIndex(int index, int val) {
        if(index > size) return ;

        listNode * current = head;
        for(int i = 0; i < index; ++i) {
            current = current->next;
        }
        listNode * temp = new listNode(val);
        temp->next = current->next;
        current->next = temp;

        ++size;
    }
    
    void deleteAtIndex(int index) {
        if(index > size - 1) return ;
        listNode * current = head;
        for(int i = 0; i < index; ++i) {
            current = current->next;
        }
        listNode * temp = current->next;
        current->next = current->next->next;
        delete temp;
        --size;
    }
private:
    int size;
    listNode * head;
};

206.反轉連結串列

題目連結 https://leetcode.cn/problems/reverse-linked-list/description/
文章講解 https://programmercarl.com/0206.翻轉連結串列.html
影片講解 https://www.bilibili.com/video/BV1nB4y1i7eL/?vd_source=2b5b33d3d692b0064daff4e58957fc82

  • 時間複雜度 o(n)
  • 空間複雜度 o(1)
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        // 初始化的狀態應滿足每次迭代的狀態,可以畫圖來確定如何初始胡
        ListNode * current = head;
        ListNode * previous = nullptr;
        while(current) {
            head = current->next;  // 透過head儲存current的下一個節點
            current->next = previous;
            previous = current;
            current = head;
        }
        // 迴圈結束時head為空, current為空, previous指向原連結串列最後一個節點
        return previous;
    }
};

相關文章