代码随想录训练营第三天 | 203.移处链表元素 707.设计链表 206.反转链表

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;
    }
};
posted @ 2024-05-11 14:58  深蓝von  阅读(3)  评论(0编辑  收藏  举报