数据结构之链表经典算法QJ题目

目录

    • 单链表经典算法题目
      • 1. 单链表相关经典算法OJ题:移除链表元素
        • 思路一:
        • 思路二:
      • 2. 单链表相关经典算法QI题:链表的中间节点
        • 思路一
        • 思路二
      • 3. 单链表相关经典算法QJ题:反转链表
        • 思路一
        • 思路二
      • 4. 单链表相关经典算法QJ题:合并两个有序链表
        • 思路
      • 5. 循环链表经典应用:环形链表的约瑟夫问题
        • 思路
      • 6. 单链表相关经典算法 QJ题:分割链表
        • 思路

单链表经典算法题目

1. 单链表相关经典算法OJ题:移除链表元素

题目路径(点击练习):

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

思路一:

遍历原链表,遇到val就执行删除val节点的操作

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {
    
		//当链表的头结点的值为val时
       while(head && head->val==val)
    {
        head = head->next;
    }
    //当链表为空的时候,直接返回
     if (head == NULL) {
        return head;
    }   
      
    struct ListNode* pre = head;//定义临时指针指向与head一致

   
     while (pre->next)
    {
    	 //当链表指向的下一个节点的值为val
        if (pre->next->val == val) {
            pre->next = pre->next->next;   
        } else {
            /* 没找到,则继续遍历查找 */
            pre = pre->next;
        }
    }
    return head;
}



思路二:

定义新链表,遍历原链表找不为val的节点,尾插在新链表中

在这里插入图片描述

链表为空:插入进来的节点就是链表的头结点和尾结点

链表不为空:插入进来的节点就是新的尾结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode* newHead = NULL;
    struct ListNode* newtail = NULL;
    struct ListNode* pcur = head;

    while(pcur)
    {
        //当原链表pcur的val不为查找的val时,将此节点尾插到新节点中,否则就继续往下走
        if(pcur->val != val)
        {
            //当链表为空
            if(newHead == NULL)
            {
                newHead = newtail = pcur;
            }else{
                //链表不为空
                newtail->next = pcur;
                newtail = newtail->next;
            }
        }
        pcur = pcur->next;
    }

    if(newtail)
        {
            newtail->next=NULL;
        }
    return newHead;
}

2. 单链表相关经典算法QI题:链表的中间节点

题目路径(点击练习)

题目

在这里插入图片描述

思路一

使用循环遍历统计链表中的个数

使用for循环根据除以2结果走到中间节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head) {
    struct ListNode* pre= head;
    int flag = 0;//用于计数
    while(pre)
    {
        flag++;//统计链表的个数
        pre=pre->next;
    }
    
   int mid = flag/2;//获取中间的位置
   pre=head;
   for(int i=0;i<mid;i++)
   {
       pre=pre->next;
   }
    return pre;
}
思路二

根据快慢指针

先定义两个指针
slow指针每走一步
fast指针每走两步

当fast->next 为空,则slow刚好指向的就是中间节点

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* middleNode(struct ListNode* head) {  
    //定义两个指针
    struct ListNode* slow = head;
    struct ListNode* fast = head;

    while(fast&&fast->next)
    {
        slow = slow->next;//一次走一步
        fast = fast->next->next;//一次走两步。当fase走完的时候slow指向的就是中间的节点
    }
    return slow;
}

3. 单链表相关经典算法QJ题:反转链表

题目路径(点击练习)

题目:

在这里插入图片描述

思路一

简单迭代

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
   //定义两个指针
   struct ListNode* temp = NULL;
   struct ListNode* curr = NULL;
   //循环遍历head
    while(head){
        temp = head->next;
        head->next = curr;
        curr = head;
        head = temp;//head和temp已被事实上置空了,防止跑飞
    }
    return curr;

}
思路二

创建三个指针

分别记录前驱结点,当前节点,后继节点,改变原链表指针方向
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    //处理空链表
    if(head==NULL)
    {
        return head;
    }
    
    //创建三个指针,分别记录前驱节点,当前节点以及后继节点
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = head;
    struct ListNode* n3 = head->next;

    while(n2)
    {
        n2->next = n1;

        n1 = n2;
        n2 = n3;
        if(n3)
        {
            n3 = n3->next;
        }
    }
 return n1;
}

4. 单链表相关经典算法QJ题:合并两个有序链表

题目路径(点击练习)

题目

在这里插入图片描述

思路

在两个原链表中创建两个指针l1,l2
再创建一个新链表

l1和l2相比较,较小值的放入新链表中
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {

    //当list1为空时直接返回list2
   if(list1 == NULL)
   {
       return list2;
   }
   //同理
   if(list2 == NULL)
   {
       return list1;
   }

   struct ListNode* l1 = list1;
   struct ListNode* l2 = list2;

   struct ListNode* newHead = NULL;
   struct ListNode* newTail = NULL;


   while(l1 && l2)
   {
       //当l1<l2
       if(l1->val < l2->val)
       {
           //判读链表是否为空
           if(newHead == NULL)
           {
               newHead = newTail = l1;
           }else{
               newTail->next = l1;
               newTail = newTail->next;
           }
           l1 = l1->next;
       }//l2<l1
       else{
           if(newHead == NULL)
           {
               newHead = newTail = l2;
           }else{
               newTail->next = l2;
               newTail = newTail->next;
           }
           l2=l2->next;
       }
       
   }
      //跳出循环时,出现两种情况l1为空,或者l2为空
      if(l1)
      {
          newTail->next = l1;
      }
      if(l2)
      {
          newTail->next = l2;
      }

   return newHead;
}

但是我们可以看到,上述出现了重复的代码,如何优化解决呢?

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {

    //当list1为空时直接返回list2
   if(list1 == NULL)
   {
       return list2;
   }
   //同理
   if(list2 == NULL)
   {
       return list1;
   }

    ListNode* l1 = list1;
    ListNode* l2 = list2;

   ListNode* newHead,*newTail;//申请一块哨兵位
   newHead=newTail=(ListNode*)malloc(sizeof(ListNode));
   while(l1 && l2)
   {
       //当l1<l2
       if(l1->val < l2->val)
       {
           newTail->next = l1;
           newTail = newTail->next;
           l1 = l1->next;
       }//l2<l1
       else{
           newTail->next = l2;
           newTail = newTail->next;
           l2=l2->next;
       }
       
   }
      //跳出循环时,出现两种情况l1为空,或者l2为空
      if(l1)
      {
          newTail->next = l1;
      }
      if(l2)
      {
          newTail->next = l2;
      }

      
    //malloc开辟了空间,但是这块空间用不了得释放掉
    ListNode* ret = newHead->next;
    free(newHead);  

   return ret;
}

5. 循环链表经典应用:环形链表的约瑟夫问题

著名的Josephus问题 据说著名犹太 Josephus有过以下的故事:
~
在罗⻢⼈占领乔塔帕特后,39 个犹太⼈与Josephus及他的朋友躲到⼀个洞中,39个犹太⼈决定宁愿死也不要被⼈抓到,于是决定了⼀个⾃杀 ⽅式,41个⼈排成⼀个圆圈,由第1个⼈开始报数,每报数到第3⼈该⼈就必须⾃杀,然后再由下⼀ 个重新报数,直到所有⼈都⾃杀⾝亡为⽌。 历史学家
然⽽Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与⾃⼰安排在 第16个与第31个位置,于是逃过了这场死亡游戏。

题目

题目路径(点击练习)

在这里插入图片描述

思路

根据n来创建不带头单向链表
逢m删除当前节点

在这里插入图片描述

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param n int整型 
 * @param m int整型 
 * @return int整型
 */

 typedef struct ListNode ListNode;

 ListNode* BuyNode(int x)
 {
    ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
    newnode->val = x;
    newnode->next = NULL;
    return newnode;
 }

 ListNode* createList(int n)
 {
    ListNode* phead = BuyNode(1);
    ListNode* ptail = phead;
    for(int i = 2;i<=n;i++)
    {
        ptail->next=BuyNode(i);
        ptail = ptail->next;
    }
    //链表要首尾相连使其循环起来
    ptail->next = phead;
    return phead;
 }
int ysf(int n, int m ) {
    //根据n来创建不带头单向链表
    ListNode* head = createList(n);
    ListNode* pcur = head;
    ListNode* prev = NULL;
    int count = 1;
    //逢m删除当前节点
    while(pcur->next != pcur)
    {
       if(count == m)
       {
        //删除当前节点
        prev->next = pcur->next;
        free(pcur);
        pcur = prev->next;
        count = 1;

       }else{
        prev = pcur;
        pcur = pcur->next;
        count++;
       }
    }
    //此时,节点便是唯一幸存下来的
    return pcur->val;
}

6. 单链表相关经典算法 QJ题:分割链表

题目路径(点击练习)

题目

在这里插入图片描述

思路

定义两个链表:大链表和小链表,遍历原来的节点将其放入对应的新链表中,最后将大链表和小链表的首尾相连

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
    //小链表
    ListNode* lessHead,*lessTail;
    lessHead = lessTail = (ListNode*)malloc(sizeof(ListNode));//创建哨兵位

    //大链表
    ListNode* greaterHead,*greaterTail;
    greaterHead = greaterTail = (ListNode*)malloc(sizeof(ListNode));//创建哨兵位

    ListNode* pcur = head;

    while(pcur)
    {
        if(pcur->val < x)
        {
            lessTail->next = pcur;
            lessTail = lessTail->next;
        }else{
            greaterTail->next = pcur;
            greaterTail = greaterTail->next;
        }
        pcur = pcur->next;
    }
    
    greaterTail->next = NULL;
    lessTail->next = greaterHead->next;

    ListNode* ret = lessHead->next;
    free(lessHead);
    free(greaterHead);
    return ret;
}

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

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

相关文章

微信小程序 ---- 慕尚花坊 项目初始化

目录 项目介绍 01. 项目概述 02. 项目演示 03. 项目技术栈 04. 接口文档 申请开发权限 项目初始化 01. 创建项目与项目初始化 02. 自定义构建 npm 集成Sass 03. 集成项目页面文件 04. VsCode 开发小程序项目 项目介绍 01. 项目概述 [慕尚花坊] 是一款 同城鲜花订购…

文心一言 VS 讯飞星火 VS chatgpt (199)-- 算法导论15.2 1题

一、用go语言&#xff0c;对矩阵规模序列(5&#xff0c;10&#xff0c;3&#xff0c;12&#xff0c;5&#xff0c;50&#xff0c;6)&#xff0c;求矩阵链最优括号化方案。 文心一言&#xff0c;代码正常运行&#xff1a; 在Go语言中&#xff0c;为了找到矩阵链乘法的最优括号…

【鸿蒙 HarmonyOS 4.0】TypeScript开发语言

一、背景 HarmonyOS 应用的主要开发语言是 ArkTS&#xff0c;它由 TypeScript&#xff08;简称TS&#xff09;扩展而来&#xff0c;在继承TypeScript语法的基础上进行了一系列优化&#xff0c;使开发者能够以更简洁、更自然的方式开发应用。值得注意的是&#xff0c;TypeScrip…

普中51单片机学习(串口通信)

串口通信 原理 计算机通信是将计算机技术和通信技术的相结合&#xff0c;完成计算机与外部设备或计算机与计算机之间的信息交换 。可以分为两大类&#xff1a;并行通信与串行通信。并行通信通常是将数据字节的各位用多条数据线同时进行传送 。控制简单、传输速度快&#xff1…

QT-Day3

思维导图 作业 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码…

minium-小程序自动化测试框架

提起 UI 自动化测试&#xff0c;web 端常用 Selenium&#xff0c;手机端常用 Appium&#xff0c;那么很火的微信小程序可以用什么工具来进行自动化测试&#xff1f;本篇将介绍一款专门用于微信小程序的自动化测试工具 - minium。 简介 minium 是为小程序专门开发的自动化框架…

职业技能鉴定服务中心前端静态页面(官网+证书查询)

有个朋友想做职业技能培训&#xff0c;会发证书&#xff0c;证书可以在自己网站可查。想做一个这样的网站&#xff0c;而且要特别土&#xff0c;一眼看上去像xxx官方网站&#xff0c;像jsp .net技术开发的网站。用htmlcssjquery还原了这样子一个前端页面&#xff0c;这里分享给…

字节一面 : post为什么会发送两次请求?

同源策略 在浏览器中&#xff0c;内容是很开放的&#xff0c;任何资源都可以接入其中&#xff0c;如 JavaScript 文件、图片、音频、视频等资源&#xff0c;甚至可以下载其他站点的可执行文件。 但也不是说浏览器就是完全自由的&#xff0c;如果不加以控制&#xff0c;就会出…

【JVM】五种对象引用

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;JVM ⛺️稳中求进&#xff0c;晒太阳 几种常见的对象引用 可达性算法中描述的对象引用&#xff0c;一般指的是强引用&#xff0c;即是GCRoot对象对普通对象有引用关系&#xff0c;只要这层…

C++ 基础算法 双指针 数组元素的目标和

给定两个升序排序的有序数组 A 和 B &#xff0c;以及一个目标值 x 。 数组下标从 0 开始。 请你求出满足 A[i]B[j]x 的数对 (i,j) 。 数据保证有唯一解。 输入格式 第一行包含三个整数 n,m,x &#xff0c;分别表示 A 的长度&#xff0c;B 的长度以及目标值 x 。 第二行包…

游戏配置二级缓存一致性问题解决方案

游戏服务器进程在启动的时候&#xff0c;一般会把所有策划配置数据加载到内存里&#xff0c;将主键以及对应的记录存放在一个HashMap容器里&#xff0c;这称为一级缓存。部分功能可能还需要缓存其他数据&#xff0c;这些称为二级缓存。举个例子&#xff0c;对于如下的玩家升级表…

【嵌入式学习】QT-Day3-Qt基础

1> 思维导图 https://lingjun.life/wiki/EmbeddedNote/20QT 2> 完善登录界面 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后…

代码随想录算法训练营第22天|235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

235.二叉搜索树的最近公共祖先 思路:这题可以利用二叉搜索树的特性能更明确的去左右方向找pq。所以什么遍历顺序都可以。 如果pq的值都小于root值,说明pq一定在左子树,去左子树遍历。 如果pq的值都大于root值,则在右子树。 排除以上两种情况,最后一种情况就是pq分别在root左…

金蝶云星空使用插件打开单据列表

文章目录 金蝶云星空使用插件打开单据列表核心代码操作测试 金蝶云星空使用插件打开单据列表 核心代码 表单插件-按钮点击事件 ListShowParameter showParam new ListShowParameter();showParam.IsLookUp false;//是否查找数据showParam.OpenStyle.ShowType ShowType.Moda…

【SQL注入】靶场SQLI DUMB SERIES-24通过二次注入重置用户密码

先使用已知信息admin/admin登录进去查下题&#xff0c;发现可以修改密码 猜测可能存在的SQL语句&#xff1a;UPDATE user SET password新密码 WHERE user用户名 and password旧密码 假设我们知道有个admin用户&#xff0c;但是不知道其密码&#xff0c;如何可以将其密码重置&…

费舍尔FISHER金属探测器探测仪维修F70

美国FISHER LABS费舍尔地下金属探测器&#xff0c;金属探测仪等维修&#xff08;考古探金银铜探宝等仪器&#xff09;。 费舍尔F70视听目标ID金属探测器&#xff0c;Fisher 金属探测器公司成立于1931年&#xff0c;在实验条件很艰苦的情况下&#xff0c;研发出了地下金属探测器…

Elasticsearch Update By Query详解

1. 使用场景 一般在以下几种情况时&#xff0c;我们需要重建索引&#xff1a; 索引的 Mappings 发生变更&#xff1a;字段类型更改&#xff0c;分词器及字典更新 索引的 Setting 发生变更&#xff1a;索引的主分片数发生改变 集群内&#xff0c;集群间需要做数据迁移 Elastiic…

【AIGC】基于深度学习的图像生成与增强技术

摘要&#xff1a; 本论文探讨基于深度学习的图像生成与增强技术在图像处理和计算机视觉领域的应用。我们综合分析了主流的深度学习模型&#xff0c;特别是生成对抗网络&#xff08;GAN&#xff09;和变分自编码器&#xff08;VAE&#xff09;等&#xff0c;并就它们在实际应用中…

电商平台商家结算

本文主要分析了目前电商清结算的流程以及自己对电商清结算的看法。 基本概念 先说下电商平台清结算的概念。简单说就是收的用户&#xff08;C端&#xff09;的付款&#xff0c;经过清分&#xff0c;再结算给对应商家。当然&#xff0c;这里排除那种资金不通过第三方&#xff0c…

一线城市打工人的大龄焦虑:都市容不下躯壳,老家容不下灵魂(含华为 OD 面试原题)

互联网的大龄焦虑 今天看到一个老生常谈的话题「大龄焦虑&#xff1a;都市容不下躯壳&#xff0c;老家容不下灵魂」。 现如今&#xff0c;内卷已不是互联网行业专属名称&#xff0c;早已渗透到一线城市中的各行各业。 但地域落差对职业的影响&#xff0c;互联网行业还是稳稳的位…