数据结构——单链表OJ题

在这里插入图片描述

单链表OJ题

  • 前言
  • 一、删除链表中等于给定值 val 的所有节点
  • 二、反转一个单链表
  • 三、返回链表的中间结点
  • 四、输出该链表中倒数第k个结点
  • 五、将两个有序链表合并
  • 六、链表的回文结构
  • 七、将链表分割成两部分
  • 八、找出第一个公共结点
  • 九、判断链表中是否有环
  • 总结


前言

在前面的博客中我们知道了什么是单链表以及如何建立单链表!
现在让我们来检验一下学习成果吧!

提示:此博客中题目均来自牛客网以及力扣网!在题目中我会附带两大网站的链接,大家也可以去练习一下!
若有链接问题可以在评论区及时反馈!


一、删除链表中等于给定值 val 的所有节点

题目链接:OJ链接
在这里插入图片描述

提示:
列表中的节点数目在范围 [0, 104] 内
1 <= Node.val <= 50
0 <= val <= 50

思路解析:
在这里插入图片描述

代码演示:

struct ListNode* removeElements(struct ListNode* head, int val) {
     struct ListNode* newhead = NULL;
     struct ListNode* move = head;
     struct ListNode* tail = NULL;

     while (move != NULL) {
         if (move->val != val) {
             if (tail == NULL) {//如果newnode为NULL,则tail等于newnode,则直接将结点地址赋予tail
                 newhead = tail = move;
                 move = move->next;
             }
             else {
                 tail->next = move;
                 move = move->next;
                 tail = tail->next;
             }
         }
         else {
             struct ListNode* temp = move;//新建结点保存要free的地址,以免free后造成节点丢失
             move = move->next;
             free(temp);
         }
     }
     if (tail)//如果新链表不为空,则将其尾结点的next置空
         tail->next = NULL;
     return newhead;
 }

二、反转一个单链表

题目链接:OJ链接
在这里插入图片描述
在这里插入图片描述

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

思路解析:
在这里插入图片描述

代码演示:

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* move1 = head;
    struct ListNode* tail = head;
    if (head == NULL || head->next == NULL) {//如果链表为空或者只有一个结点,则不需要反转
        return tail;
    }
    struct ListNode* move2 = move1->next;
    while (move2) {
        struct ListNode* temp = move2->next;//保存下一个结点的地址,防止后面的节点丢失
        move2->next = move1;
        move1 = move2;
        move2 = temp;
    }
    tail->next = NULL;//尾结点的next置空
    struct ListNode* newhead = move1;//move1最后指向了反转链表的起始结点
    return newhead;
}

三、返回链表的中间结点

题目链接:OJ链接
在这里插入图片描述

提示:
链表的结点数范围是 [1, 100]
1 <= Node.val <= 100

思路解析:
在这里插入图片描述

代码演示:

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode*move1=head;
    struct ListNode*move2=head;
    while(move2!=NULL&&move2->next!=NULL){//此处move2!=NULL和move2->next!=NULL
        move1=move1->next;                //的位置不能交换,否则会造成空指针错误
        move2=move2->next->next;
    }
    return move1;
}

四、输出该链表中倒数第k个结点

题目链接:OJ链接
在这里插入图片描述
思路解析:
在这里插入图片描述

代码演示:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    
    struct ListNode*move1=pListHead;
    struct ListNode*move2=pListHead;
    int i=k;
    while(i>0&&move2!=NULL){//move2向后移动k位
        move2=move2->next;
            i--;
    }
    if(move2==NULL&&i>0){//如果k大于链表结点数目,则返回NULL
        return move2;
    }
    while(move2){
        move1=move1->next;
        move2=move2->next;
    }
    return move1;
}

五、将两个有序链表合并

题目链接:OJ链接
在这里插入图片描述
在这里插入图片描述

提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

思路解析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码演示:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    
    struct ListNode*move1=list1;
    struct ListNode*move2=list2;
    struct ListNode*newnode=NULL;
    struct ListNode*tail=NULL;
    while(move1!=NULL&&move2!=NULL){
        if(move1->val<=move2->val){
            if(tail==NULL){{//如果newnode为NULL,则tail等于newnode,则直接将结点地址赋予tail
            newnode=tail=move1;
            move1=move1->next;
            }
            else{
                tail->next=move1;
                move1=move1->next;
                tail=tail->next;
            }
        }
        else{
            if(tail==NULL){//如果newnode为NULL,则tail等于newnode,则直接将结点地址赋予tail
                newnode=tail=move2;
                move2=move2->next;
            }
            else{
                tail->next=move2;
                move2=move2->next;
                tail=tail->next;
            }
            }
    }
    if(move1==NULL){//如果链表1遍历完而链表2没有,则将链表2剩余结点尾插到newnode中
        while(move2!=NULL){
            if(tail==NULL){//如果newnode为NULL,则tail等于newnode,则直接将结点地址赋予tail
                newnode=tail=move2;
                move2=move2->next;
            }
            else{
                tail->next=move2;
                move2=move2->next;
                tail=tail->next;
            }
        }
    }
      if(move2==NULL){//如果链表2遍历完而链表1没有,则将链表1剩余结点尾插到newnode中
        while(move1!=NULL){
           if(tail==NULL){//如果newnode为NULL,则tail等于newnode,则直接将结点地址赋予tail
            newnode=tail=move1;
            move1=move1->next;
            }
            else{
                tail->next=move1;
                move1=move1->next;
                tail=tail->next;
            }
        }
    }
      return newnode;
}

六、链表的回文结构

题目链接:OJ链接

在这里插入图片描述
思路解析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码演示:

bool chkPalindrome(struct ListNode* A) {
    struct ListNode* move1 = A;
    struct ListNode* move2 = A;
    struct ListNode* move3 = A;
    struct ListNode* newnode = NULL;
    struct ListNode* tail = NULL;
    while (move2 != NULL&&move2->next != NULL ) {//找到中间节点
        move1 = move1->next;
        move2 = move2->next->next;
    }
    if (move2 == NULL);//如果节点个数为奇数,则move1向后移动一位
    else {
        move1 = move1->next;
    }
    while (move1 != NULL) {//将后半段链表头插到newnode中
        if (newnode == NULL) {
            newnode = tail = move1;
            move1 = move1->next;
            tail->next = NULL;
        }
        else {
            struct ListNode* temp = move1->next;
            move1->next = newnode;
            newnode = move1;
            move1 = temp;
        }
    }
    struct ListNode* cmp = newnode;
    while (move3 != NULL && cmp != NULL) {//比较原链表前半段和newnode是否相同
        if (move3->val != cmp->val) {
            return 0;
        }
        else {
            move3 = move3->next;
            cmp = cmp->next;
        }
    }
    return 1;
}

七、将链表分割成两部分

题目链接:OJ链接
在这里插入图片描述
思路解析:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

代码演示:

ListNode* partition(ListNode* pHead, int x) {
        struct ListNode*head1=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*head2=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*tail1=head1;
        struct ListNode*tail2=head2;
        struct ListNode*move=pHead;
        while(move){
            if(move->val<x){
                tail1->next=move;
                move=move->next;
                tail1=tail1->next;
            }
            else{
                tail2->next=move;
                move=move->next;
                tail2=tail2->next;
            }
            }
        tail2->next=NULL;//将尾指针的next置空
        tail1->next=head2->next;
        struct ListNode*temp1=head1;
        struct ListNode*temp2=head2;
        head1=head1->next;//指针指向头结点的下一节点
        free(temp1);//释放掉创建的头结点
        free(temp2);
        return head1;
    }

八、找出第一个公共结点

题目链接:OJ链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:
函数返回结果后,链表必须 保持其原始结构 。

思路解析:
在这里插入图片描述
在这里插入图片描述

代码演示:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *move1=headA;
    struct ListNode *move2=headB;
    int len1=1,len2=1;
    while(move1){//得到链表A的长度
        move1=move1->next;
        len1++;
    }
    while(move2){//得到链表B的长度
        move2=move2->next;
        len2++;
    }
    int k=abs(len1-len2);//取相减的绝对值
    struct ListNode *moveA=headA;
    struct ListNode *moveB=headB;
    if(len1>len2){//较长的链表走k步
        while(k--){
            moveA=moveA->next;
        }
    }
      if(len1<len2){
        while(k--){
            moveB=moveB->next;
        }
    }
      while(moveA&&moveB){
        if(moveA==moveB)
            return moveA;//若地址相同则返回
        moveA=moveA->next;
        moveB=moveB->next;
    }
    return NULL;

九、判断链表中是否有环

题目链接:OJ链接
在这里插入图片描述
在这里插入图片描述

提示:

链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。

思路解析:
在这里插入图片描述

代码演示:

bool hasCycle(struct ListNode *head) {
    struct ListNode*move1=head;
    struct ListNode*move2=head;
    while(move1&&move2&&move2->next){//此处move2和move2->next的顺序不可交换
        move1=move1->next;           //否则会导致空指针错误
        move2=move2->next->next;
        if(move1==move2)
            return true;
    }
    return false;
}

总结

这九道单链表OJ都是我见过的很经典的题型!
在这里为大家分享一下!
希望有更多的人能够通过这些题目更好地掌握单链表相关的知识!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/54960.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中国农村程序员学习此【JavaScript教程】购买大平层,开上帕拉梅拉,迎娶白富美出任CEO走上人生巅峰

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录 在 Switch 语句添加多个相同选项从函数返回布尔值--聪明方法undefined创建 JavaScript 对象通过点号表示法访问对象属性使用方括号表示法访问对象属性通过变量访问对象属性给 JavaScript 对象添加新属性删除…

青大数据结构【2016】

一、单选 二、简答 3.简述遍历二叉树的含义及常见的方法。 4.简要说明图的邻接表的构成。 按顺序将图G中的顶点数据存储在一维数组中&#xff0c; 每一个顶点vi分别建立一个单链表&#xff0c;单链表关联依附顶点vi的边&#xff08;有向图为以vi为尾的弧&#xff09;。 邻接…

[LeetCode]只出现一次的数字相关题目(c语言实现)

文章目录 LeetCode136. 只出现一次的数字ⅠLeetCode137. 只出现一次的数字 IILeetCode260. 只出现一次的数字 IIILeetCode268. 丢失的数字 LeetCode136. 只出现一次的数字Ⅰ 题目: 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元…

Pytorch深度学习-----神经网络的基本骨架-nn.Module的使用

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接

前言&#xff1a;最近项目上需要使用富文本编辑器&#xff0c;觉得tinymce很不错就用了&#xff0c;具体怎么在项目中使用参考 【vue】 vue2 中使用 Tinymce 富文本编辑器 【vue】 Tinymce 数据 回显问题 | 第一次正常回显后面&#xff0c;显示空白bug不能编辑 这两天又遇到了…

“用户登录”测试用例总结

前言&#xff1a;作为测试工程师&#xff0c;你的目标是要保证系统在各种应用场景下的功能是符合设计要求的&#xff0c;所以你需要考虑的测试用例就需要更多、更全面。鉴于面试中经常会问“”如何测试用户登录“”&#xff0c;我们利用等价类划分、边界值分析等设计一些测试用…

iOS--frame和bounds

坐标系 首先&#xff0c;我们来看一下iOS特有的坐标系&#xff0c;在iOS坐标系中以左上角为坐标原点&#xff0c;往右为X正方向&#xff0c;往下是Y正方向如下图&#xff1a; bounds和frame都是属于CGRect类型的结构体&#xff0c;系统的定义如下&#xff0c;包含一个CGPoint…

【Docker】初识Docker以及Docker安装与阿里云镜像配置

目录 一、初识Docker 二、安装Docker 三、Docker架构 四、配置Docker镜像加速器 一、初识Docker Docker是一个开源的应用容器引擎&#xff0c;诞生于2013年&#xff0c;基于Go语言实现&#xff0c;dotCloud公司出品&#xff0c;Docker开源让开发者打包他们的应用以及依赖包到…

我的会议(会议通知)

前言: 我们在实现了发布会议功能&#xff0c;我的会议功能的基础上&#xff0c;继续来实现会议通知的功能。 4.1实现的特色功能&#xff1a; 当有会议要参加时&#xff0c;通过查询会议通知可以知道会议的内容&#xff0c;以及当前会议状态&#xff08;未读&#xff09; 4.2思路…

Python selenium对应的浏览器chromedriver版本不一致

1、chrome和chromedriver版本不一致导致的&#xff0c;我们只需要升级下chromedriver的版本即可 浏览器版本查看 //打开google浏览器直接访问&#xff0c;查看浏览器版本 chrome://version/ 查看chromedriver的版本 //查看驱动版本 chromedriver chromedriver下载 可看到浏…

在 Amazon EMR 上构建实时数据湖

前言 当公司业务发展遇到瓶颈时&#xff0c;业务分析师以及决策者们总会希望通过交叉分析大量的业务数据和用户行为数据&#xff0c;以解答“为什么利润会下滑&#xff1f;”“为什么库存周转变慢了&#xff1f;”等问题&#xff0c;最终整点“干货”出来从而促进业务发展。 …

一文了解JavaScript 与 TypeScript的区别

TypeScript 和 JavaScript 是两种互补的技术&#xff0c;共同推动前端和后端开发。在本文中&#xff0c;我们将带您快速了解JavaScript 与 TypeScript的区别。 一、TypeScript 和 JavaScript 之间的区别 JavaScript 和 TypeScript 看起来非常相似&#xff0c;但有一个重要的区…

替换linux的文泉驿正黑fonts-wqy-zenhei字体 替换linux默认中文字体

WSL 怎么替换 linux 的文泉驿正黑 fonts-wqy-zenhei 字体 WSL 怎么替换 linux 默认中文字体 在 wsl 中默认是没有 gnome 界面或者 xface 的&#xff0c;但是我需要使用 wsl 开发 electron 或者使用 chrome 浏览器。这个时候系统就会调用默认的系统字体了。 我使用的是 debian…

风辞远的科技茶屋:来自未来的信号枪

很久之前&#xff0c;有位朋友问我&#xff0c;现在科技资讯这么发达了&#xff0c;你们还写啊写做什么呢&#xff1f; 我是这么看的。最终能够凝结为资讯的那个新闻点&#xff0c;其实是一系列事情最终得出的结果&#xff0c;而这个结果又会带来更多新的结果。其中这些“得出”…

低代码开发平台源码:基于模型驱动,内置功能强大的建模引擎,零代码也能快速创建智能化、移动化的企业应用程序

管理后台低代码PaaS平台是一款基于 Salesforce Platform 的开源替代方案&#xff0c;旨在为企业提供高效、灵活、易于使用的低代码开发平台。低代码PaaS平台的10大核心引擎功能:1.建模引擎 2.移动引擎 3.流程引擎 4.页面引擎 5.报表引擎 6.安全引擎 7.API引擎 8.应用集成引擎 9…

SkyEye与Jenkins的DevOps持续集成解决方案

在技术飞速发展的当下&#xff0c;随着各行各业的软件逻辑复杂程度提升带来的需求变更&#xff0c;传统测试已无法满足与之相对应的一系列测试任务&#xff0c;有必要引入一个自动化、可持续集成构建的DevOps平台来解决此类问题。本文将主要介绍SkyEye与Jenkins的持续集成解决方…

IDEA中文UT方法执行报错问题、wps默认保存格式

wps默认保存格式、IDEA中文UT方法执行报错问题 背景 1、wps修改文件后&#xff0c;编码格式从UTF-8-bom变成UTF-8&#xff08;notepad可以查看&#xff09;&#xff1b; 2、IDEA中文UT执行报错&#xff1a; 解决方案 1、语言设置中不要勾选 “Beta版。。。。” 2、cmd中执…

视频传输网安全防护体系

在电脑、手机信息安全保护得到广泛关注和普及的今天&#xff0c;监控摄像头等设备的安全防护仍为大众所忽略&#xff0c;大量视频监控网络的前端设备和数据没有任何保护&#xff0c;完全暴露在互联网中。 前端IP接入设备与后端业务系统处于直连状态&#xff0c;一旦有攻击者或…

iOS开发-UIScrollView嵌套tableView实现顶部tab横向切换

iOS开发-UIScrollView嵌套tableView实现顶部tab横向切换 通过ScollView嵌套两个TableView左右切换功能 一、UIScollView UIScrollView可滚动控件&#xff0c;这里初始化需要设置_backScollView.pagingEnabled YES; 代码如下 _backScollView [[UIScrollView alloc] initWi…

98. Python基础教程:try...except...finally语句

【目录】 文章目录 1. try...except...finally语法介绍2. try...except...finally执行顺序3. 捕获特定类型的异常4. 捕获所有类型的异常5. 实操练习-打开txt文件并输出文件内容 【正文】 在今天的课程中&#xff0c;我们将学习Python中的异常处理语句try...except...finally。 …