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

203. 移除链表元素 - 力扣(LeetCode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/remove-linked-list-elements/203和206都是以前刷过的,但是隔了好久再做时候,细节还是会有一点问题,链表问题大多都可以用虚拟头结点的方法,使链表的插入和删除操作变得简单。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode dummyhead;
        dummyhead.next=head;
        ListNode* cur=&dummyhead;
        while(cur&&cur->next)
        {
            if(cur->next->val==val){
                ListNode*tmp=cur->next;
                 cur->next=cur->next->next;
                delete tmp;
            }
            else
            cur=cur->next;
        }
        return dummyhead.next;
    }
};

这道题并不难,值得注意的是,创建一个临时指针,指向head,然后判断它的值是否等于val,要注意的是用cur->next->val来判断值是否是我们需要找的,如果是的话,cur指向的正是要删除节点的上一个节点,直接将cur的next指针连到要删除节点的下一个位置就可以了,这是非常重要的思路要删除节点的上一个节点要能够被找到。如果不是正常指向下一个节点就可以了,思路清晰很容易ac。


206. 反转链表 - 力扣(LeetCode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/reverse-linked-list/反转链表更是老生常谈的话题了,之前链表做过的第一道题就是反转链表,不过那时候是在牛客。

思路明确的同时还要注意head指针传进来时,若是空的情况要怎么处理,以及应该创建几个临时节点,分别保存什么。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL)return head;
        ListNode* next=head->next;
         ListNode* ret=NULL;
        ListNode* cur=head;
        while(cur)
        {
           cur->next=ret;
           ret=cur;
           cur=next;
           if(next)
           next=next->next;
        }
    return ret;
    }
};

要明确的是创立三个临时指针,一个用来保存要反转的节点的下一个链接节点,一个用来指向下一个反转节点的next连接到哪里,另一个代表当前要反转的节点。缺一不可的,一开始ret要指向null,使第一个反转的链表有指向的指针,只要明确要用到几个指针,以及分别初始化为什么值,这道题就很容易解的出来了。

递归代码也给出,和上面的方法思路是相同的,不做赘述。

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

707. 设计链表 - 力扣(LeetCode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/design-linked-list/设计链表是一道综合题,涵盖了很多有关于链表的函数接口,适合练习,整体思路不算很难,但是对于我这个c++初学者,有蛮多语法细节搞不太懂(之前主要是写c的)

class MyLinkedList {
public:
struct LinkNode{
    int val;
    LinkNode* next;
    LinkNode(int val):val(val),next(nullptr){}
};
    MyLinkedList() {
        dummyhead=new LinkNode(0);
        size=0;
    }
    
    int get(int index) {
        if(index<0)return -1;
        else if(index>size-1)return -1;
        LinkNode*cur=dummyhead->next;
        while(index--){
            cur=cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        LinkNode*cur=dummyhead;
      LinkNode*  tmp=new LinkNode(val);
        tmp->next=cur->next;
        cur->next=tmp;
        size++;
    }
    
    void addAtTail(int val) {
        LinkNode*cur=dummyhead;
        LinkNode* tmp=new LinkNode(val);
        while(cur->next){
            cur=cur->next;
        }
        cur->next=tmp;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        LinkNode*cur=dummyhead;
       if(index==size){
           addAtTail(val);return;
       }
       else if(index>size)return;
       else if(index<0){
           addAtHead(val);return;
       }

        while(index--){
            cur=cur->next;
        }
        LinkNode* tmp=new LinkNode(val);
        tmp->next=cur->next;
        cur->next=tmp;size++;
    }
    
    void deleteAtIndex(int index) {
        LinkNode*cur=dummyhead;
        if(index>=size||index<0)return;
        while(index--){
            cur=cur->next;
        }
        cur->next=cur->next->next;
        size--;
    }
    private :
    int size;
    LinkNode* dummyhead;
};

起初写的时候很懵逼,还在想为什么没有给头节点指针,而是只有index?后来看题解才知道要自己创建结构体,和虚拟头节点(方便空链表插入)。但是对于结构体里的构造函数的创建,和最后虚拟节点才进行数据类型的定义还是有些许不理解,应该取看看语法了。。。

回归主题,整体思路难度适中,只是接口多了一些,思路清晰还是能写出得出来的。

代码均可ac,有用记得三连哦!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我知道了。以下是对您的问题的回答: a. 动态分配内存的方法有很多,可以使用C语言的malloc函数,也可以使用C++中的new操作符,具体方法如下: C语言的malloc函数: ```c struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode)); ``` C++中的new操作符: ```c++ ListNode* node = new ListNode(); ``` b. 初始化单链表需要对链表节点的成员变量进行赋值,以下是一个示例: ```c++ struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* head = NULL; ``` c. 头插法创建单链表的示例代码如下: ```c++ ListNode* head = new ListNode(); head->next = NULL; for (int i = 0; i < n; i++) { int x; cin >> x; ListNode* node = new ListNode(x); node->next = head->next; head->next = node; } ``` 尾插法创建单链表的示例代码如下: ```c++ ListNode* head = new ListNode(); head->next = NULL; ListNode* tail = head; for (int i = 0; i < n; i++) { int x; cin >> x; ListNode* node = new ListNode(x); node->next = NULL; tail->next = node; tail = node; } ``` d. 取链表某一位的值可以通过遍历链表来实现,以下是一个示例: ```c++ ListNode* p = head->next; int pos = 3; for (int i = 1; i < pos && p != NULL; i++) { p = p->next; } if (p == NULL) { cout << "链表长度不足" << endl; } else { cout << p->val << endl; } ``` e. 在链表的某一位进行插入操作可以通过遍历链表找到插入位置,然后插入一个新节点来实现,以下是一个示例: ```c++ ListNode* p = head; int pos = 3; for (int i = 1; i < pos && p != NULL; i++) { p = p->next; } if (p == NULL) { cout << "链表长度不足" << endl; } else { int x = 100; ListNode* node = new ListNode(x); node->next = p->next; p->next = node; } ``` f. 遍历链表可以通过循环遍历链表节点来实现,以下是一个示例: ```c++ ListNode* p = head->next; while (p != NULL) { cout << p->val << " "; p = p->next; } cout << endl; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习算法的杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值