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

203.移除链表元素

要点:加入一个虚拟头节点会省心很多

方法:

假设 A -> B -> C 三个节点,B是要删除的节点,B删除后,A->next就变为C

所以要删除一个节点,要关注三个节点,被删除的B,B前面的A,B后面的C

A:需要修改next指针 

B:需要delete释放空间

C:需要暂时用变量保存一下,方便A指向

如果从虚拟头节点开始遍历,遍历到底C为nullptr

A - cur B - cur->next C - cur->next->next

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* temp_head = new ListNode(0);
        temp_head->next = head;
        ListNode* cur = temp_head;
        while (cur->next != nullptr) {
            if (cur->next->val == val) {
                ListNode* del_node = cur->next;
                cur->next = cur->next->next;
                delete del_node;
            } else {
                cur = cur->next;
            }
        }
        head =  temp_head->next;
        delete temp_head;
        return head;
    }
};

707.设计链表

要点:如果要学链表的话,必然需要学自定义一个链表,包括链表的增删改查操作

题目中是查增(头、尾、指定index)删(指定index)

改的操作与查类似,查出来后修改节点的val即可

同样也是需要关注要操作节点的前后节点,有虚拟头节点会舒服很多

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) return;
        if (index < 0) index = 0;
        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* temp = cur->next;
        cur->next = temp->next;
        delete temp;
        temp = nullptr;
        _size--;
    }
private:
    int _size;
    LinkedNode* _dummyHead;
};

206.反转链表

要点:改变整个链表的指针方向,即全部朝后的,反转成全部朝前的,头上加个nullptr,尾巴的nullptr不要

看懂双指针和递归的原理后,记住先保存,再转向,再移动,就不会出错

方法:

需要两个指针,pre和cur

pre初始化为nullptr,插在原链表的头上,开始遍历

1. 保存 temp = cur->next;

2. 转向 cur-next = pre;(本来pre是指向cur的,反转成cur指向pre)

3. 移动 pre = cur; cur = temp;

遍历到最后,pre就是反转后链表的头节点,cur为nullptr

class Solution {
public:
    ListNode* reverse(ListNode* pre, ListNode* cur) {
        if (cur == NULL)
            return pre;
        ListNode* temp = cur->next;
        cur->next = pre;
        return reverse(cur, temp);
    }

    ListNode* reverseList(ListNode* head) { return reverse(nullptr, head); }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值