首页 > 其他分享 >代码随想录打卡Day3

代码随想录打卡Day3

时间:2024-10-19 08:48:48浏览次数:11  
标签:index head ListNode cur 随想录 Day3 next 打卡 节点

链表:

通过指针链接的线性数据结构。链表由两部分组成,一为数据域,一为指针域。

并与结构体有很大关系,链表的节点一般都是结构体,其中包含了该节点的数据部分以及指向下一节点的指针。通过这种方式,链表将结构体与指针连接起来,从而构建一个强大的数据结构,可以同时实现数据的组织和动态管理。

定义结构体:

struct 结构体名称 {
    类型 成员1;
    类型 成员2;
    // 更多成员定义
};

单链表节点的建立:

struct Node
{
    int data;//数据域
    Node *next;//指针域
};

单链表的节点删除

1)单链表仅含一个节点,删除头节点

head=NULL;
delete head;

  简单明了,将头节点设为NULL(即为空),不能忘了delete!

2)单链表含至少两个节点,删除头节点

ListNode*p=head;
head=head->next;
delete p;

注意先将原head保存,用于delete。

3)单链表含至少两个节点,删除非头节点

ListNode*p=head;
while(p->next!=DelNode)
    p=p->next;
p->next=DelNode->next;
delete DelNode;

根据上述运算

易得题解代码

class Solution {
public:
    //删除头节点
    ListNode* removeElements(ListNode* head, int val) {
        //判断头节点是否为空且值为val
        while(head!=NULL&&head->val==val){
            ListNode*p=head;//设定探测指针p
            head=head->next;//探测指针前进
            delete p;//删除节点
        }
        ListNode*cur=head;//设定cur指针,用于在遍历链表是指向当前位置
        /*提出循环条件cur不能后是最后两个节点,
        与"if(cur!=NULL&&cur->next!=NULLL)"遥遥相对*/
        while(cur!=NULL&&cur->next!=NULL){
            //
            if(cur->next->val==val){
                ListNode*p=cur->next;
                cur->next=p->next;//非头结点删除的操作
                delete p;
            }else{
                cur=cur->next;
            }
        
        }
        return head;
    }
};

 

该题涵盖了链表的所有基本操作,把操作填进对应的函数就行。

(设置虚拟头节点dummyhead)题解代码:

class MyLinkedList {
public:
    // 定义链表节点结构体
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

    // 初始化链表
    MyLinkedList() {
        _dummyHead = new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        _size = 0;
    }

    // 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
    int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){ // 如果--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++;
    }

    // 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
    // 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
    // 如果index大于链表的长度,则返回空
    // 如果index小于0,则在头部插入节点
    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++;
    }

    // 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        //delete命令指示释放了tmp指针原本所指的那部分内存,
        //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
        //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
        //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
        tmp=nullptr;
        _size--;
    }

    // 打印链表
    void printLinkedList() {
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
    }
private:
    int _size;
    LinkedNode* _dummyHead;

};

 简单来说,就是对原头节点进行去特殊化。

 

法一双指针法

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

 注意pre,cur,temp三个的先后顺序就行。

法二递归

class Solution {
public:
    ListNode* reverse(ListNode* pre,ListNode* cur){
        if(cur == NULL) return pre;
        ListNode* temp = cur->next;
        cur->next = pre;
        // 可以和双指针法的代码进行对比,如下递归的写法,其实就是做了这两步
        // pre = cur;
        // cur = temp;
        return reverse(cur,temp);
    }
    ListNode* reverseList(ListNode* head) {
        // 和双指针法初始化是一样的逻辑
        // ListNode* cur = head;
        // ListNode* pre = NULL;
        return reverse(NULL, head);
    }

};

标签:index,head,ListNode,cur,随想录,Day3,next,打卡,节点
From: https://blog.csdn.net/2401_86177347/article/details/143064457

相关文章

  • 代码随想录算法训练营day19| 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插
    学习资料:https://programmercarl.com/0235.二叉搜索树的最近公共祖先.html****学习记录:235.二叉搜索树的最近公共祖先(加一个函数traversal)点击查看代码#Definitionforabinarytreenode.#classTreeNode(object):#def__init__(self,x):#self.val=x......
  • 代码随想录算法训练营day18 |530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数
    学习资料:https://programmercarl.com/0530.二叉搜索树的最小绝对差.html530.二叉搜索树的最小绝对差(双指针法,pre&cur,设置最小差值初始为无穷大,当差值<最小差值就更新最小差值)点击查看代码#Definitionforabinarytreenode.#classTreeNode(object):#def__init__(......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    1前言今日主要学习链表的基础leetcode203移除链表元素leetcode707设计链表leetcode206反转链表2链表的基础链表分为单链表和双链表,与字符串的区别就是链表是在一个里面存储了数据+下一个数据的内存地址链表中存储的内存空间是可以不连续的2.1链表的定义2.1.1......
  • 代码随想录算法训练营 | 115.不同的子序列,583. 两个字符串的删除操作,72. 编辑距离
    115.不同的子序列题目链接:115.不同的子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰不同的子序列日期:2024-10-18想法:dp[i][j]表示以s[i-1],t[j-1]结尾的s,t自学列中满足s的子序列为t的个数,如果s[i-1],t[j-1]相等,那么个数应该跟双方上一个结尾状态dp[i-1][j-......
  • 20241018打卡
    Simai是一种用于绘制maimaiDX谱面的脚本语言,主要用于定义游戏中的音符位置、类型和时间,使玩家能够在触摸屏上按照音乐节奏进行操作。这种语言广泛用于创建自定义谱面,为maimaiDX提供独特的挑战和体验。Simai语言的基本语法:文件头和元数据:通常在脚本开头定义一些元数据,......
  • 打卡信奥刷题(069)用C++工具信奥P11076[普及组/提高] 「FSLOI Round I」单挑
    「FSLOIRoundI」单挑题目背景Englishstatement.YoumustsubmityourcodeattheChineseversionofthestatement.小F和小S经常进行篮球单挑,但小S总是被盖帽。题目描述每次单挑的结果一定是小F获胜或者小S获胜,不存在平局的情况。由于小F和小S实......
  • 代码随想录算法训练营 | 1143.最长公共子序列,1035.不相交的线,53. 最大子序和,392.判断
    1143.最长公共子序列题目链接:1143.最长公共子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰最长公共子序列日期:2024-10-17想法:这里的子序列不要求连续了,dp[i][j]要表示为在text1[0,i-1]和text2[0,j-1]的范围里,最长的公共子序列长度,-1同样是为了初始化方便,如果te......
  • 代码随想录算法训练营第二天|209长度最小的子数组、59螺旋矩阵
    1leetcode209长度最小的子数组题目链接:209.长度最小的子数组文章链接:代码随想录(programmercarl.com)视频链接:拿下滑动窗口!|LeetCode209长度最小的子数组思路:没有思路,看到这道题有一种想立马退出的感觉,无从下手1.1暴力搜索1.1.1python版本这个版本的新知识就是定义......
  • 代码随想录|二叉树part 03
    求普通二叉树的节点数量要点:将子节点的个数记录到父节点,使用后序遍历classSolution{public:intmaxDepth(TreeNode*root){if(root==NULL)return0;intleft1=maxDepth(root->left);intright1=maxDepth(root->right);intnum=......
  • 代码随想录|二叉树part 02
    翻转二叉树要点:指针交换优先利用前序或后序遍历,若采用中序遍历(则两次采用遍历左子树)classSolution{public:TreeNode*invertTree(TreeNode*root){if(root==NULL)returnroot;swap(root->left,root->right);invertTree(root->left);......