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

203.移除链表元素

题目:力扣题目链接

视频:代码随想录视频讲解

在写代码时出现的问题:

ListNode* p,q;这么写是错误的,这样只能定义p.

可以分开定义。

方法一:直接删除元素

需要单独讨论一下当需要删除的元素位于头结点时的情况。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while(head!=nullptr&&head->val==val)//while容易写成if,例如1,1,1,1,1,1 val=1
        {
            head=head->next;
        }
        ListNode* p=head,*q;
        while(head!=nullptr&&p->next!=nullptr&&p!=nullptr)
        {
            if(p->next->val==val)
            {
                q=p->next;
                p->next=q->next;
                delete q;
            }
            else//注意这里,当删除p后面的数时,还要检查一下if语句中的P的新的next符不符合
            p=p->next;
        }
        return head;
    }
};

方法二:设置一个哨兵结点,也叫虚拟头结点

在头结点前设置虚拟头结点,可以避免多讨论头结点删除的情况。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* currenthead=new ListNode();
        ListNode* p;
        ListNode* q=currenthead;//q是用来遍历的,p是辅助删除的
        currenthead->next=head;
        while(q->next!=nullptr)
        {
            if(q->next->val==val)
            {
                p=q->next;
                q->next=p->next;
                delete p;
            }
            else 
            q=q->next;
        }
        return currenthead->next;
    }
};

707.设计链表

题目:力扣题目链接

视频:代码随想录视频讲解

获取链表中下标为 index 的节点的值的简单写法:

while(index>0)

{

        index--;

        p=p->next;

}

return p->val;

需要注意以下几点:

1.构造函数的写法

2.定义结点的写法

3.函数间的调用

代码

class MyLinkedList {
public:
    struct ListNode {
        int val;
        ListNode* next;
        ListNode(int x) : val(x), next(nullptr) {}
    };
    MyLinkedList() {
        _dummyHead = new ListNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        size = 0;
    }
    
    int get(int index) { 
        if(index<0||index>size-1)
        return -1;
        ListNode* p=_dummyHead->next;
        while(index>0)
        {
            index--;
            p=p->next;
        }
        return p->val;
    }
    
    void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    void addAtIndex(int index, int val) {
        if (index < 0 || index > size) {
            return;
        }
        ListNode* s=new ListNode(val);
        ListNode* p=_dummyHead;
        while(index>0)
        {
            index--;
            p=p->next;
        }
        s->next=p->next;
        p->next=s;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if(index<0||index>size-1)
        return;
        ListNode* p=_dummyHead;
        while(index>0)
        {
            index--;
            p=p->next;
        }
        ListNode* q=p->next;
        p->next=q->next;
        delete q;
        size--;
    }
private:
    int size;
    ListNode* _dummyHead;
};

206.反转链表

题目:力扣题目链接

视频:代码随想录视频讲解

方法一:双指针

注意定义指针的写法。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre=nullptr;
        ListNode* current=head;
        ListNode* tempt;
        while(current!=nullptr)
        {
            tempt=current->next;
            current->next=pre;
            pre=current;
            current=tempt;
        }
        return pre;
    }
};

方法二:递归

在打代码的过程中出现的问题:

问题在于递归调用 reverse 时没有正确处理返回值。此外,reverseList 和 reverse 函数的返回类型是 ListNode*,但在递归调用中没有正确返回翻转后的链表头。(函数与返回值要对应)

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        return reverse(head,nullptr);
    }
    ListNode* reverse(ListNode* current,ListNode* pre)
    {
        ListNode* tempt;
        if(current==nullptr)
        return pre;
        tempt=current->next;
        current->next=pre;
        return reverse(tempt,current);
    }
};

总结:

1.构造函数的写法

2.定义结点的写法

3.函数间的调用

4.定义指针的写法

5.获取链表中第n个结点的数值的简单思路

6.(函数与返回值要对应)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值