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

代码随想录刷题2022.02.07

链表相关操作1

LeetCode题目1

203. 移除链表元素

解题要点

1)链表的实际指针过程可以简化理解为:

cur:当前节点地址;

cur->next:下一个节点地址;

cur->next->next:下下个节点地址;

注意:应当防止curNULL以及cur->nextNULL

2)对单向链表,由于只能得知后一个节点的信息,因此,移除元素时,应从该移除元素的上一个节点处开始;

3)创建节点指针时,应立刻初始化,或使用new()实现内存初始化;

代码过程

1)原链表分类删除法

/**
 * 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* removeElements(ListNode* head, int val) {
        while(head!=NULL&&head->val==val){
            head=head->next;
        }
        ListNode* cur=head;
        while(cur!=NULL&&cur->next!=NULL){
            if(cur->next->val==val){
                cur->next=cur->next->next;
            }
            else
                cur=cur->next;
        }
        return 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* removeElements(ListNode* head, int val) {
        ListNode* dummyhead=new(ListNode);
        dummyhead->next=head;
        ListNode* cur=dummyhead;
        while(cur!=NULL&&cur->next!=NULL)
        {
            if(cur->next->val==val){
                cur->next=cur->next->next;
            }
            else
                cur=cur->next;
        }
        return dummyhead->next;
    }
};

LeetCode题目2

707. 设计链表

解题思路

1)用结构体struct定义(并初始化)链表;

2)当出现"第n个节点"时,定义一个“cur”指针来遍历链表,找到对应的第n个位置

    LinkedNode* cur=_dummyhead->next;
    while(index)
    {
       cur=cur->next;
       index--;
    }

3)添加节点或删除节点时,都从要添加的那个节点开始操作:

i)添加节点时,从要添加的那个节点开始先链接下个节点;

ii)删除节点时,先将要删除的那个节点进行复制,以备delete释放内存。

代码过程
class MyLinkedList {
public:
    struct LinkedNode{
        int val;
        struct LinkedNode* next;
        LinkedNode(int val):val(val),next(nullptr){}//结构体初始化
    };
    //类使用构造函数初始化;
    MyLinkedList() {
        _dummyhead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        _size = 0;
    }
    //获取链表中第 index 个节点的值。如果索引无效,则返回-1。
    int get(int index) {
        if(index<0||index>(_size-1))return -1;
        LinkedNode* cur=_dummyhead->next;
        while(index)
        {
            cur=cur->next;
            index--;
        }
        return cur->val;
    }
    //在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
    void addAtHead(int val) {
        LinkedNode* temp=new LinkedNode(val);
        temp->next=_dummyhead->next;
        _dummyhead->next=temp;
        _size++;
    }
    //将值为 val 的节点追加到链表的最后一个元素.
    void addAtTail(int val) {
        LinkedNode* newnode=new LinkedNode(val);
        LinkedNode* cur=_dummyhead;
        while(cur->next!=NULL)
        {
            cur=cur->next;
        }
        cur->next=newnode;
        _size++;
    }
    //在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
    void addAtIndex(int index, int val) {
        if(index>_size)return;
        if(index<0)index=0;
        LinkedNode* cur=_dummyhead;
        while(index)
        {
            cur=cur->next;
            index--;
        }
        LinkedNode* newnode=new LinkedNode(val);
        newnode->next=cur->next;
        cur->next=newnode;
        _size++;
    }
    //如果索引 index 有效,则删除链表中的第 index 个节点。
    void deleteAtIndex(int index) {
        if(index<0||index>=_size)return;
        LinkedNode* cur=_dummyhead;
        while(index)
        {
            cur=cur->next;
            index--;
        }
        LinkedNode* temp=cur->next;
        cur->next=cur->next->next;
        delete(temp);
        _size--;
    }
    
private:
    int _size;
    LinkedNode* _dummyhead;
};

/**
 * 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);
 */

LeetCode题目3

206. 反转链表

解题思路

1)迭代法:初始条件+终止条件+迭代式

2)递归法:终止条件+初始条件+递归式(结合栈上函数的开始与结束来进行分析)

代码过程

1)迭代法

/**
 * 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* cur=head;
        ListNode* pre=NULL;
        while(cur!=NULL)//终止条件
        {
            //迭代关系
            ListNode* temp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
};

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* reverseList(ListNode* head) {
        //特例情况
        if(head==NULL)return NULL;
        //终止条件
        if(head->next==NULL){
            return head;;
        }
        //先向前遍历再向后遍历,结合栈的特点进行分析
        ListNode* last=reverseList(head->next);//初始条件
        //递归式
        ListNode* temp=head->next;
        temp->next=head;
        head->next=NULL;
        return last;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值