代码随想录刷题Day3 | 203.移除链表元素、707.设计链表、206.反转链表

今日任务

203.移除链表元素
707.设计链表
206.反转链表

203.移除链表元素

先将头部连续的val节点删除,实际工程中记得释放堆空间

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

// #define _DELETE_HEAP

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
#ifdef _DELETE_HEAP
        ListNode *tmp;
#endif

        while (head && head->val == val) {

#ifdef _DELETE_HEAP
            tmp = head;
#endif

            head = head->next;

#ifdef _DELETE_HEAP
            delete tmp;
#endif

        }

        ListNode *newHead = head, *p = head;

        while (p) {
            while (p->next && p->next->val == val) {

#ifdef _DELETE_HEAP
                tmp = p->next;
#endif

                p->next = p->next->next;

#ifdef _DELETE_HEAP
                delete tmp;
#endif
            }
            p = p->next;
        }

        return newHead;
    }
};

707.设计链表

没啥难度,但是注意节点判空等细节,然后可以使用虚拟头节点来简化程序

// #define _DEBUG

struct LinkNode {
    int val = -1;
    LinkNode *prev = nullptr, *next = nullptr;
    LinkNode() = default;
    LinkNode(int _val, LinkNode *_prev = nullptr, LinkNode *_next = nullptr) : val(_val), prev(_prev), next(_next) {}
};

class MyLinkedList {
public:
    MyLinkedList() {
        dummyHead = new LinkNode();
        dummyTail = new LinkNode();
        dummyHead->next = dummyTail;
        dummyTail->prev = dummyHead;
    }
    
    int get(int index) {
        if (index < 0 || index >= size) return -1;
        LinkNode *pCur = dummyHead->next;
        while (index--) {
            pCur = pCur->next;
        }
        return pCur->val;

#ifdef _DEBUG
        print();
#endif
    }
    
    void addAtHead(int val) {
        LinkNode *p = new LinkNode(val);
        // 先在链外以p为节点接一根线
        p->prev = dummyHead;
        p->next = dummyHead->next;
        // 再把链内原来的线重新接到p上
        dummyHead->next->prev = p;
        dummyHead->next = p;
        ++size;

#ifdef _DEBUG
        print();
#endif
    }
    
    void addAtTail(int val) {
        LinkNode *p = new LinkNode(val);
        p->next = dummyTail;
        p->prev = dummyTail->prev;
        dummyTail->prev->next = p;
        dummyTail->prev = p;
        ++size;

#ifdef _DEBUG
        print();
#endif
    }
    
    void addAtIndex(int index, int val) {
        if (index > size) return ;
        else if (index < 0) addAtHead(val);
        else if (index == size) addAtTail(val);
        else {
            LinkNode *pCur = dummyHead->next;
            while (index--) { // 0的时候不进入循环,因为pCur初始值为第0个节点
                pCur = pCur->next;
            }
            // 前插
            LinkNode *p = new LinkNode(val);
            p->prev = pCur->prev;
            p->next = pCur;
            pCur->prev->next = p;
            pCur->prev = p;
            ++size;
        }
#ifdef _DEBUG
        print();
#endif
    }
    
    void deleteAtIndex(int index) {
        if (index >= 0 && index < size) {
            LinkNode *pCur = dummyHead->next;
            while (index--) { // 0的时候不进入循环,因为pCur初始值为第0个节点
                pCur = pCur->next;
            }
            pCur->prev->next = pCur->next;
            pCur->next->prev = pCur->prev;
            delete pCur;
            --size;
        }

#ifdef _DEBUG
        print();
#endif

    }

    void print() {
        if (size == 0) return ;
        LinkNode *p = dummyHead->next;
        while (p != dummyTail) {
            cout << p->val << ' ';
            p = p->next;
        }
        cout << "size = " << size;
        cout << endl;
    }

private:
    LinkNode *dummyHead, *dummyTail;
    int size = 0;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

206.反转链表

方法一:遍历头插法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *tmp = nullptr, *newHead = nullptr;
        while (head) {
            tmp = head;
            head = head->next;
            tmp->next = newHead;
            newHead = tmp;
        }
        return newHead;
    }
};

方法二:改成递归版本头插法
1.原始递归

class Solution {
public:
    // 递归写法
    ListNode* reverse(ListNode* newHead, ListNode* cur) {
        if (cur == nullptr) return newHead;

        ListNode *tmp = cur;
        cur = cur->next;
        tmp->next = newHead;

        return reverse(tmp, cur);
    }

    ListNode* reverseList(ListNode* head) {

        return reverse(nullptr, head);
    }
};

2.简化版递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode *newHead, ListNode* cur) {
        if (cur == nullptr) return newHead;
        ListNode* tmp = cur->next;
        cur->next = newHead;
        return reverse(cur, tmp);
    }

    ListNode* reverseList(ListNode* head) {
        return reverse(nullptr, head);
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值