首页 > 其他分享 >LeetCode刷题day3——链表part1

LeetCode刷题day3——链表part1

时间:2024-06-22 00:01:19浏览次数:16  
标签:head ListNode cur val day3 next 链表 part1 size

203.移除链表元素

这个题是二刷了一开始这个思路就是利用虚拟头结点,但是中间很多小细节都考虑不到,例如初始化一个新的链表,循环条件的写法等

class Solution {
public:
struct ListNode{
    int val;
    ListNode *next;
    ListNode(int x):val(x),next(NULL){};//定义构造函数
};
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummy_head = new ListNode(0);//忘记初始化
        dummy_head->next = head;
        ListNode *cur;
        cur = dummy_head;
        //指向虚拟头节点,应该从下一个开始
        while(cur->next!=NULL){
            if(cur->next->val == val){
                ListNode *tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }else{
                cur = cur->next;
            }
        }
        //循环完了要记得处理虚拟头结点
        head = dummy_head->next;
        delete dummy_head;
        return head;

    }
};

但是报错

Line 46: Char 49: error: cannot initialize a parameter of type
'ListNode ’ (aka 'Solution::ListNode ') with an lvalue of type
'ListNode ’ 46 | ListNode ret =
Solution().removeElements(param_1, param_2); return ret;
| ^~~~~~~ Line 18: Char 40: note: passing argument to parameter ‘head’ here 18 |
ListNode
removeElements(ListNode
head, int val) {
| ^

所以如果不定义构造函数使用默认构造函数的话,在初始化的时候就不能直接给变量赋值!注意卡哥说的在C++里面,要自己定义,leetcode里面默认的是可以直接赋值的。
因此代码将struct 链表定义删掉即可。

707.设计链表

问题:1.不知道初始化什么对象,以及里面要定义哪些值。2.index非法情况怎么具体在代码中体现。3.边界处理不到位,比如=size =0这些我还自己分开讨论,其实可以写在一起。

class MyLinkedList {
public:
    struct ListNode {
        int val;
        ListNode* next;
        ListNode(int x) : val(x), next(NULL){};
    };
    MyLinkedList() {
        // 初始化 MyLinkedList 对象

        // 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回
        // void 构造函数可用于为某些成员变量设置初始值
        dummy_head = new ListNode(0);
        size = 0;
    }

    int get(int index) {
        if (index >= (size) || index < 0) // =size-1是最后一个节点 =size就无效了
            return -1;
        ListNode* cur = dummy_head->next;
        while (index--) {
            cur = cur->next;
        }
        return cur->val;
    }

    void addAtHead(int val) {
        ListNode* node = new ListNode(val);
        node->next = dummy_head->next;
        dummy_head->next = node;
        size++;
    }

    void addAtTail(int val) {
        ListNode* cur = dummy_head;   // 卡哥没指向next,注意不能指向,因为有可能一开始是空的,就没有next一说
        ListNode* node = new ListNode(val); // 这个要初始化为val不能是0
        while (cur->next != NULL) {
            cur = cur->next;
        }
        cur->next = node;
        // node->next = NULL; //不用再指向空
        size++;
    }

    void addAtIndex(int index, int val) {
        if (index > size || index < 0) {
            return;
        }
        ListNode* cur = dummy_head; // 不能next,因为要找插入节点的前一个节点
        ListNode* node = new ListNode(val); // 这个要初始化为val不能是0
        // 这个循环适用于index = 0/size
        while (index--) {
            cur = cur->next;
        }
        node->next = cur->next;
        cur->next = node;
        size++; // 忘记size++了
    }

    void deleteAtIndex(int index) {
    if (index >= size || index < 0) { // 注意这里是=,=size就超过最后一个节点无效了
        return;
    }
    ListNode* cur = dummy_head; // 不能next,因为要找delete节点的前一个节点
    // 这个循环适用于index = 0/size
    while (index--) {
        cur = cur->next;
    }

    ListNode* tmp = cur->next;
    cur->next = cur->next->next;
    delete tmp;
    // delete命令指示释放了tmp指针原本所指的那部分内存,
    // 被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
    // 如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
    // 如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
    tmp = nullptr;
    size--;//!!!!delete之后size--
}
private:
    int size;
    ListNode* dummy_head;
};

206.反转链表(双指针/递归)

  1. 双指针法

考虑用双指针法,但自己想的时候还是串联不起来思路。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* cur = head;
        ListNode* pre = nullptr;
        while(cur!=nullptr){
            ListNode* tmp = cur->next;//储存下一个值
            cur->next = pre;
            //pre cur ++
            pre = cur;
            cur = tmp;
        }

        return pre;//因为循环结束,cur=null是最后一个节点之后
    }
};
  1. 递归
    和双指针思路基本一致,需要定义一个reverse函数,一直递归调用,两个传递参数(pre,cur),但是主函数只有一个head,怎么传递?那根据一开始的初始化来说,cur=head,pre=null,所以传递为reverse(head,null)。剩下的思路与双指针基本一致,所以很好写。
// 递归
class Solution {
public:
    ListNode* reverse(ListNode* cur, ListNode* pre) { // 两个传递参数,但是主函数只有一个head,怎么传递?
        if (cur == nullptr) {
            return pre;
        }
        ListNode* tmp = cur->next; // 储存下一个值
        cur->next = pre;
        return reverse(tmp, cur);
    }

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

标签:head,ListNode,cur,val,day3,next,链表,part1,size
From: https://blog.csdn.net/nosnef/article/details/139787044

相关文章

  • LeetCode刷题day4——链表part2
    24.两两交换链表中的节点用pre代表第1个节点,cur代表它后面的相邻节点,tmp存储cur->next。但是问题找不到怎么返回新的节点。想着就循环一次,在第一次交换的时候就确认新的头结点。但还存在很多问题,具体如下:classSolution{public:ListNode*swapPairs(ListNode*he......
  • 【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
                   ......
  • JOISC 2024 Day3 T1 : Card Collection / 卡牌收集
    首先,注意到对于一组询问,我们只需要关注每个数与\((T_j,W_j)\)的相对大小关系。这一共有\(9\)种情况,于是我们直接做区间DP,设一个形如\(f(l,r,0/1/2,0/1/2)\)的状态,即可得到\(O(N^3M)\)的做法;进一步使用bitset优化可以做到\(O(\frac{N^3M}{w})\),但是无法通过(甚至\(N=20......
  • 一千题,No.0089(链表元素分类)
    给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而[0,K]区间内的元素都排在大于K的元素前面。但每一类内部元素的顺序是不能改变的。例如:给定链表为18→7→-4→0→5→-6→10→11→-2,K为10,则输出应该为-4→-6→-2→7→0→5→10......
  • c语音实现单链表初始化的四种方式
    typedefstructmyLink{ intdata; structmyLink*next;}myLink,*myLLink;1、对于上面的简单结构,用函数赋值需要传递引用,需要用到指针的指针。对指针使用不是很清楚的童鞋很是头痛。voidinitlink(myLink**head){ *head=(myLink*)malloc(sizeof(myLink)); if(......
  • 链表插入的小技巧
    一个带有优先级的链表:structlist{structlist*next;u32priority;} 如果要按照优先级插入某个新节点node,算法一般会写成:intlist_insert(list**head,list*new){if(head==null||*head==null||new==null)return1;list*prev......
  • 算法题---判断链表中是否有环,并找出环的入口
    方案一、利用Set集合不会重复的原理booleanjudgeCycle(Nodehead){Set<Node>visited=newHashSet<>();Nodenode=head;while(node!=null){if(visited.contains(node))returntrue;visi......
  • Day28.property使用part1
    1.property使用part1 @property用法,代码如下:#装饰器是在不修改被装饰对象源代码以及调用方式的前提下为被装饰对象添加#新功能的可调用对象#property是一个装饰器,用来将绑定给对象的方法,伪装成一个数据属性(即不需要加`()`调用)'''成人的BMI数值:过轻:低于18.5......
  • 黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day3
    你好,我是Qiuner.为帮助别人少走弯路和记录自己编程学习过程而写博客这是我的githubhttps://github.com/Qiuner⭐️giteehttps://gitee.com/Qiuner......
  • MySQL-Day3
    学习目标写SQL三步法边写边运行,否则后面出错时候会难以排查搭框架基本的select语句框架建起来,如果有多表,把相应的多表联合起来看条件决定where后面的显示的字段select后面的内容连接查询内连接两张表相同地方select*from 左/右连接包括内连接以及左/右部......