【链表OJ】链表中倒数第k个结点 合并两个链表(含哨兵位) 分割链表 链表的回文结构

news2024/10/5 21:25:35

前言:

💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥

✨✨刷题专栏:http://t.csdn.cn/UlvTc

⛳⛳本篇内容:力扣和牛客上链表OJ题目

目录

 一、链表中倒数第k个结点

题目描述:

解题思路:

二.合并两个链表(含哨兵位) 

题目描述:

解题思路: 

                                           不含哨兵位

三.分割链表 

题目描述:

解题思路:

四.链表的回文结构

题目描述:

解题思路:


 一、链表中倒数第k个结点

来源:链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

题目描述:

输入一个链表,输出该链表中倒数第k个结点。

示例:

输入:1,{1,2,3,4,5}

返回值:{5}

解题思路:

  1. 创建两个指针,一个名为fast(快指针),另一个则是slow(慢指针),同时把头结点的地址赋值给二者,也就意味着两个指针同时指向头结点。
  2. 通过传参传过来的参数k的含义是该链表中倒数的第k个结点
  3. 进入第一个while循环中,k--多少次也就意味着fast指针先走k步
  4. 接着进入第二个while循环,以fast!=NULL为循环的条件
  5. 接着两指针一起走相同的步数,待fast指向NULL结束,此时正好是slow指向的链表中倒数第k个结点
  6. 返回slow指针
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    struct ListNode* fast = pListHead, * slow = pListHead;
    while (k--)
    {
        if (fast == NULL)// 快慢指针同时移动,直到快指针到达链表末尾
        {
            return NULL;
        }
        fast = fast->next;
    }
     while (fast)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;// 返回慢指针所指向的节点
}

 动图解析: 

执行:

二.合并两个链表(含哨兵位) 

此题来源:21. 合并两个有序链表 - 力扣(LeetCode)

题目描述:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例1:

输入:

l1 = [1,2,4], l2 = [1,3,4]

 输出:

[1,1,2,3,4,4]

解题思路: 

主要思路跟这篇的思路相差不大

不含哨兵位

二级指针解法请看->【链表OJ 5】合并两个有序链表_Dream_Chaser~的博客-CSDN博客

唯一区别如下:

首先,malloc一个哨兵位的头节点,

接着创建两个指针:head和tail,并让它们指向哨兵位的头节点。

注意:

        此头结点不存储任何数据,使用时不用判断tail指针指向的结点是否为NULL,因为tail指向的哨兵位绝对不为NULL,添加时只需要在哨兵位的头节点后面链接上新结点即可。

        最后记得销毁掉这个头节点。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
   if(list1==NULL)
      return list2;
   if(list2 ==NULL)
      return list1;
   struct ListNode*head=NULL,*tail=NULL;
   head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
   while(list1 && list2)
   {
     if(list1->val < list2->val)
     {   //不用判断tail是否指向NULL,需要的时候直接在tail后面链接即可
         tail->next=list1;
         tail=tail->next;
         list1=list1->next;
     }
      else
      {
         tail->next=list2;
         tail=tail->next;
         list2=list2->next;
      }
   }
     if(list1)
     {
        tail->next=list1;
     }
     if(list2)
     {
       tail->next=list2;
     }
  
    //记得销毁哨兵位的头节点
     struct ListNode* del=head;
     head=head->next;
     free(del);
    return head;//链表的第一个有效的结点
 }

执行:

 

三.分割链表 

来源:链表分割_牛客题霸_牛客网 (nowcoder.com)

题目描述:

        现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

示例:假定x为5

输入:原链表顺序

 输出:返回链表

解题思路:

1.创建两个带头结点(这题一定要含哨兵位,不然很麻烦)的单链表

        1️⃣lesshead:指向比x值小的链表的哨兵位(第一个链表)

        2️⃣lesstail:用于遍历第一个链表(比x小的),以及链接比x值小的结点,最后待cur指向NULL时,链接到greaterhead,将两个链表链接起来

        3️⃣greaterhead:指向比x值大的链表的哨兵位(第二个链表),与lesstail链接起来

        4️⃣greatertail:用于遍历第二个链表(比x大的),以及链接比x值大的结点,最后一定要把greatertail置空,因为在原链表中,greatertail指向的这个值还存着下一个结点的地址,它的next有可能是NULL,也有可能不是NULL

        如果greatertail指向的这个值不为NULL,若此时不置空,则会出现环状链表的情况。

2.cur用于遍历原始链表是否结束的条件,若cur不指向NULL,则遍历原始链表,若指向NULL,则表示lesshead与greaterhead指向的两个链表尾插完毕。

3.判断

        比x小的,用lesstail访问哨兵位的next与cur指向的当前结点链接起来,之后

lesstail=lesstail->next, 准备尾插第二个结点。

        比x大的,用greatertail访问哨兵位的next与cur指向的当前结点链接起来,之后greatertail=greatertail->next, 准备尾插第二个结点。

4.接着待两个链表尾插结束,要记得lesstai的next与greaterhead->head链接起来,接着greatertail置空。

5.然后原始链表头结点pHead要用lesshead->next赋值向后更新一位,此时才是改变后的链表的头结点。

6.将两个哨兵位free掉,接着返回pHead,打印链表。

初始情况:

 

  动图解析:

 最终的情况:

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x)
    {
    struct ListNode* lesshead,*lesstail,*greaterhead,*greatertail;
    lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
    greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
       
    struct ListNode* cur=pHead;
    while(cur)
{
    if(cur->val < x)
    {
       lesstail->next=cur;
       lesstail =lesstail->next;
    }
    else
    {
        greatertail->next =cur;
        greatertail=greatertail->next;
    }
        cur=cur->next;
        }
        lesstail->next=greaterhead->next;
        greatertail->next=NULL;

        pHead=lesshead->next;
        free(lesshead);
        free(greaterhead);
    return pHead;
}
};

执行:

四.链表的回文结构

来源:LCR 027. 回文链表 - 力扣(LeetCode)

题目描述:

给你一个单链表的头节点 head,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

示例 1:

输入:head = [1,2,2,1]

输出: true

 示例 2:

输入: head = [1,2]

输出: false

解题思路:

        先找到中间结点,然后将中间结点mid指向的链表反方向输出,接着用原链表头结点head指向的前半段与反向后的链表头结点rmid指向的后半段进行比较。

顺序:

        1.用快慢指针方法找到链表的中间结点,这是前半段:http://t.csdn.cn/YH93S

        2.用中间结点mid指向的链表反转,这是后半段,反转链表:http://t.csdn.cn/rf9Jl

        3. 比较链表的前半段和后半段

                若相等,则是回文结构(返回true)

                否则,不为回文结构(返回false)

动图解析:

 这里省略了反转链表的细节过程,若有需要可以看看上面的那篇文章。

//c++环境下c适用
class Solution {
public:
   struct ListNode* middleNode(struct ListNode* head) {
        struct ListNode* slow = head, *fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }
    struct ListNode* reverseList(struct ListNode* head) {
        struct ListNode* cur = head, *rhead = NULL;
        while (cur) {
            struct ListNode* next = cur->next;

            //头插
            cur->next = rhead;
            rhead = cur;
            //迭代
            cur = next;
        }
        return rhead;
    }
    bool isPalindrome(struct ListNode* head) {
        struct ListNode* mid = middleNode(head);
        struct ListNode* rmid = reverseList(mid);
        while (rmid) {
            if (rmid->val != head->val) {
                return false;
            } else {
                rmid = rmid->next;
                head = head->next;
            }
           
        } 
        return true;
    }
};
    

执行: 

         本篇结束,感谢你的来访。✨

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

热点如何用于期刊写作——以chatGPT为例

交叉领域A&#xff0c;B 以自己为例子&#xff0c;A是教育 B是技术&#xff0c;我是教育技术学专业。 经验来源 知网关于GPT的140余篇专业论文的观察 截止至2023年8月14日15:35:45 学习每出现一个热点&#xff0c;如何应用于学术。 实践阅读发现 套路一&#xff1a;谈理论…

Java通过文件流和文件地址下载文件

通过文件流下载文件 如何使用 MultipartFile 进行文件上传、下载到本地&#xff0c;并返回保存路径呢&#xff1a; import org.springframework.web.multipart.MultipartFile;import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOExcep…

发布游戏,进行打包。(Unity)

做到这里&#xff0c;我们的项目基本功能已经完成了&#xff0c;如果你还想使项目功能更加完善&#xff0c;可以自己思考如何补充&#xff0c;充分发挥并进行优化使效果达到更加美好。 首先呢&#xff0c;我们这里是说打包Window电脑游戏&#xff0c;我们直接点击菜单栏文件-&…

数据结构与算法基础(青岛大学-王卓)(7)

差点就脱更了啊&#xff0c;微臣嘴干玩死&#xff0c;忙碌的暑假&#xff0c;还有头痛的new house, 我这junk food 也是吃一大堆&#xff0c;please不要长胖啊。 图的应用 这一章内容也是很多啊&#xff0c;概念真是比牛毛还多。。。看了两遍才缓过来啊 fighting 文章目录 [toc…

DoIP学习笔记系列:(六)满足AES128-CMAC算法的“安全认证”.dll生成实践

文章目录 1. 算法Demo2. 算法实现传送门 DoIP学习笔记系列:导航篇 AES128-CMAC算法在汽车电子控制单元的软件开发中涉及到安全相关的需求经经常用到,具体的算法原理请各位小伙伴自行百度,本篇主要向大家分享该算法如何集成到.dll文件中,在OTA、刷写等场景作为$27服务的安全…

Python实现透明隧道爬虫ip:不影响现有网络结构

作为一名专业爬虫程序员&#xff0c;我们常常需要使用隧道代理来保护个人隐私和访问互联网资源。本文将分享如何使用Python实现透明隧道代理&#xff0c;以便在保护隐私的同时不影响现有网络结构。通过实际操作示例和专业的解析&#xff0c;我们将带您深入了解透明隧道代理的工…

微服务相关面试题

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱写博客的嗯哼&#xff0c;爱好Java的小菜坤 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;社区论坛&#xff1a;希望大家能加入社区共同进步…

自动化测试系列 —— UI测试

UI 测试是一种测试类型&#xff0c;也称为用户界面测试&#xff0c;通过该测试&#xff0c;我们检查应用程序的界面是否工作正常或是否存在任何妨碍用户行为且不符合书面规格的 BUG。了解用户将如何在用户和网站之间进行交互以执行 UI 测试至关重要&#xff0c;通过执行 UI 测试…

解决生成式AI落地之困,亚马逊云科技提供完整解决方案

生成式AI技术无疑是当前最大的时代想象力之一。 资本、创业者、普通人都在涌入生成式AI里去一探究竟&#xff1a;“百模大战”连夜打响&#xff0c;融资规模连创新高&#xff0c;各种消费类产品概念不断涌现……根据Bloomberg Intelligence 的报告&#xff0c;2022年生成式AI 市…

[HDLBits] Exams/m2014 q4c

Implement the following circuit: module top_module (input clk,input d, input r, // synchronous resetoutput q);always(posedge clk) beginif(r) q<1b0;elseq<d;end endmodule

万字长文·通俗易懂·一篇包掌握——输入/输出·文件操作(c语言超详细系列)(二)

前言&#xff1a;Hello&#xff0c;大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;上一节我们主要学习了格式化输入输出的基本内容&#xff0c;这一节我们对格式化进行更加深入的了解&#xff0c;对文件概念进行介绍&#xff0c;并且对输入、输出与文件读写的基本概念…

推断统计(独立样本t检验)

这里我们是采用假设检验中的独立样本t 检验来比较两个独立正态总体均值之间是否存在显著性差异&#xff0c;以比较城市与农村孩子的心理素质是否有显著差异为例 。 这里我们首先是假设城市孩子与农村孩子心理素质无显著差异&#xff0c;但是此时方差是否齐性是未知的&#xff0…

IntelliJ IDEA(简称Idea) 基本常用设置及Maven部署---详细介绍

一&#xff0c;Idea是什么&#xff1f; 前言&#xff1a; 众所周知&#xff0c;现在有许多编译工具&#xff0c;如eclipse&#xff0c;pathon, 今天所要学的Idea编译工具 Idea是JetBrains公司开发的一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于Java…

4.文件保护

第四章 文件管理 4.文件保护 ​   加密保护&#xff1a;可以用“密码”与文件的原始数据依次做异或运算。这样可以把整个文件的数据都进行加密&#xff0c;所以系统中保存的并不是文件的原始数据&#xff0c;而是保存了对文件进行加密之后的数据&#xff0c;所以如果一个用户…

Windows Oracle21C与PLSQL Developer 15配置

1、下载Oracle21c并安装 下载地址&#xff1a;https://www.oracle.com/database/technologies/oracle21c-windows-downloads.html 2、下载PLSQL Developer 15并安装 下载地址&#xff1a;https://www.allroundautomations.com/products/pl-sql-developer/#pricing 3、配置O…

Android Studio瀑布流实现

效果&#xff1a; ImageDetail class package com.example.waterfallflow; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.ImageView;public class ImageDetail extends Activity{Overrideprotected void …

SCAU操作系统知识点之(十一)I/O调度和磁盘调度

1、程序控制I/O&#xff1a;CPU忙等I/O结束&#xff0c;CPU与设备串行工作。 2、中断驱动I/O&#xff1a;各种设备通用&#xff0c;中断次数多。 3、直接存储器访问DMA原理与I/O过程。 列出并简单定义执行I/O的三种技术。 程序控制I/O&#xff1a; 处理器代表进程向I/O模…

【Java】使用JavaSE实现图书管理系统详解

目录 1.前言 2.初步框架搭建 3.Book 书架和书架里的书 3.1书本 3.2书架 4.User 用户和管理员 4.1初步想法 4.2用户 4.3管理员 4.4main函数中如何调用不同的成员 5.方法的调用 5.1接口 5.2增加图书 5.3借阅图书 5.4删除图书 5.5退出系统 5.6查找图书 5.7归还图书…

利用python实现激光雷达LAS数据滤波的7种方式,使用laspy读写

激光雷达&#xff08;LiDAR&#xff09;数据在实际应用中可能受到噪声和不完美的测量影响&#xff0c;因此数据去噪和滤波方法变得至关重要&#xff0c;以提高数据质量和准确性。以下是一些常用的激光雷达数据去噪与滤波方法。 原始数据如下&#xff1a; 1. 移动平均滤波&…

springcloud3 hystrix实现服务降级,熔断,限流以及案例配置

一 hystrix的作用 1.1 降级&#xff0c;熔断&#xff0c;限流 1.服务降级&#xff1a; A方案出现问题&#xff0c;切换到兜底方案B&#xff1b; 2.服务熔断&#xff1a;触发规则&#xff0c;出现断电限闸&#xff0c;服务降级 3.服务限流&#xff1a;限制请求数量。 二 案例…