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

Leetcode 203.移除链表元素
思路分析:
移除链表元素和移除数组元素类似,可采用覆盖的方式。链表移除head节点和非head节点有差异,应用dumy节点可以让移除head节点和非head节点的操作逻辑相同。
容易忽略的点是覆盖元素后,对应node的内存空间需要释放掉。因为没释放,leetcode上也不报错,故很容易忽略【本人就忽略了】。

代码实现:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummy = new ListNode();
        dummy->next = head;
        ListNode* cur_node = dummy;
        while (cur_node->next) {
            if (cur_node->next->val == val) {
                ListNode* tmp = cur_node->next;
                cur_node->next = cur_node->next->next;
                delete tmp;    // 注意释放被删除节点的内存
            } else {
                cur_node = cur_node->next;
            }
        }
        // return dummy->next;
        head = dummy->next;
        delete dummy;       // 注意释放被删除节点的内存
        return head;
    }
};

Leetcode 707.设计链表
思路解析:本人见本题,思路并不清晰。自己写了下,没得到期望结果。以下是参考《代码随想录》写的。
ps 待本人理解更透彻了,再更新一版。

代码实现:

class MyLinkedList {
public:
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

    MyLinkedList() {
        _dummyHead = new LinkedNode(0);
        _size = 0;
    }

    int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){
            cur = cur->next;
        }
        return cur->val;
    }

    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;
    }

    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
    }

    void addAtIndex(int index, int val) {
        if (index > _size || index < 0) {
            return;
        }
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        _size++;
    }

    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        _size--;
    }

    void printLinkedList() {
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
    }
private:
    int _size;
    LinkedNode* _dummyHead;

};

Leetcode 206.反转链表
思路分析:
可以定义pre_node,让当前节点cur_node的next指针指向pre_node,可定义pre_node的初值为空指针nullptr。
当前链表的最后一个节点即为反转链表的head节点。或cur_node的最后一个值即为反转链表的head节点。
代码实现:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre_node = nullptr;
        ListNode* cur_node = head;
        ListNode* reverse_head = nullptr;
        while (cur_node != nullptr) {
            ListNode* p_next = cur_node->next;    // next值需要先保存下来,因为后面会被覆盖
            if (cur_node->next == nullptr) {
                reverse_head = cur_node;
            }
            cur_node->next = pre_node;
            pre_node = cur_node;
            cur_node = p_next;
        }
        return reverse_head;
    }
};

你可能感兴趣的:(代码随想录训练营,链表,算法,数据结构)