leetcode链表刷题2

news2024/11/17 3:33:14

题单:

 

 

一,链表的分割

1.题目描述

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。你不需要 保留 每个分区中各节点的初始相对位置。

2.题目接口

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


struct ListNode* partition(struct ListNode* head, int x){
    

}

3.题目分析

这道题的意思很简单:就是要将一个链表内的元素按照与某个数的对比结果来排个顺序,小于某个数的在左边,大于某个数的在右边。在解这道题时需要重新定义两个链表一个存大于指定值的数据(greaderHead),一个存小于指定值的数据(smallHead)。定义好两个链表以后还需要定义两个尾节点:greaderTail,smallTail。因为在接下来我们需要进行尾插。尾插之前还需要判断:

1.当原链表为NULL时直接返回即可。

2.当链表内只有一个节点时直接返回即可

3.当链表的节点大于等于两个时才执行尾插操作。

4.解题代码

第一种:不带虚拟头节点

struct ListNode* partition(struct ListNode* head, int x){
   //当链表为NULL时直接返回返回head
   if(head == NULL)
   return head;
 
   //当链表只有一个节点时直接返回head
   if(head->next == NULL)
   return head;

   //当链表的节点个数大于等于2个时
   struct ListNode* smallHead = NULL;
   struct ListNode* smallTail = NULL;

   struct ListNode* greaderHead = NULL;
   struct ListNode* greaderTail = NULL;

   struct ListNode* cur = head;
   while(cur)
   {     //每次尾插时都需要对尾节点的指向进行置空操作,这是为了避免造成环形链表的情况
       if(cur->val>=x)
       {  
           if(greaderHead == NULL)
           {
              
               greaderHead = greaderTail = cur;
               cur = cur->next;
               greaderTail->next = NULL;//尾节点置空
           }
           else
           {
               greaderTail->next = cur;
               greaderTail = greaderTail->next;
               cur = cur->next;
               greaderTail->next = NULL;//尾节点置空
           }
       }
       else
       {
           if(smallHead == NULL)
           {
               smallHead = smallTail = cur;
               cur = cur->next;
               smallTail->next = NULL;//尾节点置空
           }
           else
           {
              smallTail->next = cur;
              smallTail = smallTail->next;
               cur = cur->next;
              smallTail->next = NULL;//尾节点置空
           }

       }

   }
   
if(smallTail)//当小的链表不为NULL时要与greaderHead链接返回
{
    smallTail->next = greaderHead;
    return smallHead;
}
return greaderHead;//当smallTail等于NULL时直接返回greaderHead即可

}

二,回文链表

1.题目描述

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

2.题目接口

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


bool isPalindrome(struct ListNode* head){

}

3.题目分析

判断是否是回文链表就像判断是否是回文数一样看前后的数据是否对称,在这里解题的步骤有三个:

1.找到中间节点。

2.从后到中间节点依次反转。

3.前后比较数值是否相同判断是否是回文链表。

4.解题代码

struct ListNode* GetMid(struct ListNode* head)//计算中间节点
{   struct ListNode* dumy = ( struct ListNode*)malloc(sizeof( struct ListNode));
dumy->next = head;
    struct ListNode* fast = dumy;
    struct ListNode* slow = dumy;
    while(fast&&fast->next){
        slow = slow->next;
       fast = fast->next->next;
    }
    return slow;
}
struct ListNode* reverse(struct ListNode*  newhead){//将中间节点后面的节点反转
    struct ListNode*  pre = NULL;
    struct ListNode*  temp = NULL;
    struct ListNode*  cur = newhead;
    while(cur){
        temp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;

}
bool isPalindrome(struct ListNode* head){
    struct ListNode* mid = GetMid(head);
    struct ListNode* cur = mid->next;
     struct ListNode*  newhead = NULL;
     struct ListNode* tail = NULL;
    while(cur){//将反转以后的链表尾插组成新的链表
        if(tail == NULL){
           newhead =  tail = cur;
        }
        else{
            tail->next = cur;
            tail = cur;
        }
        cur = cur->next;
        tail->next = NULL;

    }
    newhead = reverse(newhead);
    while(newhead){//新的链表长度小于原链表,所以用新的链表来做结束的判断条件
        if(newhead->val!=head->val){
            return false;
        }
        newhead = newhead->next;
        head = head->next;
    }
    return true;




}

三,单链表的第一个公共节点

1.题目描述

输入两个链表,找出它们的第一个公共节点。

2.题目接口

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    
}

 3.题目分析

这道题需要我们找到两个链表的相交节点,寻找相交节点的第一步便是要判断两个链表是否相交,若相交便找相交节点。

1.用两个节点指针cur1与cur2指向两个链表的头节点,遍历后让两个指针指向链表的尾节点并计算两个链表的长度。当两个链表的尾节点不是同一个时便可以判断两个链表不相交。

2.当两个链表相交时便可以让两个链表中长的那一个先走差距步再让两个链表一起走当两个指针指向同一个节点时便返回该节点。

4.解题代码

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //当两个链表中有一个为NULL时便返回NULL
    if(headA == NULL||headB==NULL)
    {
        return NULL;
    }

    //遍历两个链表计算两个链表各自的长度,并让遍历后的cur指向的是两个链表的最后一个节点。
    struct ListNode * cur1 = headA;
    struct ListNode * cur2 = headB;
    int lenA = 0;
    int lenB = 0;
    while(cur1->next)
    {
        cur1 = cur1->next;
        lenA++;
      
    }
    while(cur2->next)
    {
        cur2 = cur2->next;
        lenB++;
    }
   //当两个链表的最后一个节点不为同一个时两链表一定不相交
    if(cur1!=cur2)
    {
        return NULL;
    }

    //相交后的链表先让长的链表先走gap步,再让两个链表同时走直到指向同一个节点便返回该节点。
    int gap = abs(lenA-lenB);
    if(lenA>lenB)
    {
       while(gap)
       {
           headA = headA->next;
           gap--;
       }

    }
    else
    {
        while(gap)
       {
           headB = headB->next;
           gap--;
       }

    }
    while(headA)
    {
        if(headA==headB)
        {
            return headA;
        }
        headA = headA->next;
        headB = headB->next;
    }
   return;
}

四,环形链表

1.题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

2.题目接口

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    
}

 3.题目分析

判断链表内是否有环这道题算是很简单的题了,可以想象这是两个运动员在跑步问题。当比赛的跑道是直道那慢的运动员一定是不会和快的运动员相遇的。但是如果跑道是环形的那快的运动员就可以追上慢的运动员。按照这个思路写成的代码如下:

4.解题代码

bool hasCycle(struct ListNode *head) {
    //空链表直接返回NULL
    if(head == NULL)
    return false;
     
    //定义快慢两个指针模拟追击问题
    struct ListNode * slow = head;
    struct ListNode * fast = head;

    while(fast&&fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(slow == fast)
        {
            return true;
        }
        
    }
return false;

    
}

五,寻找链表环的入口

1.题目描述

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

2.题目接口

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

3.题目分析

这道题的解题思路是这样子的:

1.先判断链表是否有环,若有环便找到快慢指针的相遇节点。

2.找到相遇节点以后便让一个指针从链表头走,一个指针从相遇点走。当两指针再次相遇时得到的节点就是环的起始节点。

数学问题:

其实这道题就是一个数学问题:

假设有下面的环形链表:

当我们假设环的长度为C时便有:

2*(L+X)=L+X+n*C

L+X= n*C

L=n*C-X = (n-1)*C+(C-X)

所以当两个指针,一个从相遇点一个从头节点处以相同的速度开始走时就会在环的入口处相遇。

4,解题代码

struct ListNode *detectCycle(struct ListNode *head) {
    //判断是否为环并找到相遇节点。
    if(head == NULL)
    return NULL;

    struct ListNode * fast = head;
    struct ListNode * slow = head;

    while(fast&&fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        break;
    }
    if(fast==NULL||fast->next == NULL)
    {
        return NULL;
    }
    
    slow = head;
    while(1)
    {
        if(fast == slow)
        {
            return slow;
        }
        fast = fast->next;
        slow = slow->next;
    }
    return NULL;
}

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

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

相关文章

COMDEL射频电源维修康戴尔高频电源CLX2750

美国COMDEL电源维修常见型号包括:CLX2750;CLX2500;CLX-600H;CX600AS;CX-5000S;CX-3500S;CX-2500S;CV500;CDX2000等。 Comdel成立于1966年,总部设在马萨诸塞州…

STM32 10个工程篇:1.IAP远程升级(五)

伴随着催更不断,周日晚上来继续撰写STM32 IAP远程升级的项目例程,在这篇博客中笔者主要结合上位机报文发送机制来介绍下位机的报文解析设计,坚持做原创博客确实是一件很考验耐力的事情,一方面博客的文字和图片需要投入大量精力和时…

关于2023年积分落户公示及落户办理有关工作的通告

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…

Mybatis从0到1 SQL注入 参数占位符 XML配置 动态SQL

1. Mybatis基础操作 学习完mybatis入门后,我们继续学习mybatis基础操作。 1.1 需求 需求说明: 根据资料中提供的《tlias智能学习辅助系统》页面原型及需求,完成员工管理的需求开发。 通过分析以上的页面原型和需求,我们确定了功能…

【Python】使用pycharm结合gradio做一个web页面的demo

紧接上文我们安装好了python3.10,现在需要下载它的开发工具pycharm,我们在这里不过多赘述具体细节,仅简要说明关键步骤,来通过gradio体验一下示例demo 一、下载IDE pycharm官网:https://www.jetbrains.com.cn/pycharm…

Scratch 抓小狗

Scratch 抓小狗 本程序转换为HTML后运行。“小狗”角色每0.7秒复制并移动到随机位置和方向,碰到边缘反弹,碰到其它角色后删除,得分1。其它4个角色第一个跟随鼠标,其它的跟随前面的角色,后面3个角色碰到“小狗”角色则得…

第45节:cesium 卷帘效果(含源码+视频)

结果示例: 完整源码: <template><div class="viewer"><vc-viewer @ready="ready" :logo="false"></vc

Spring MVC中的HandlerInterceptors和Filters

1.介绍 比较Java servlet过滤器和Spring MVC Handlerinterceptor&#xff0c;以及什么时候一个比另一个更好。 2.Filters 过滤器是web服务器的一部分&#xff0c;而不是Spring框架。对于传入的请求&#xff0c;可以使用过滤器来操作甚至阻止请求到达任何servlet。反之亦然&a…

Bootstrap4 总结

文章目录 Bootstrap4 总结概述安装使用CDN使用源码 屏幕尺寸的分割点响应式容器(Containers).container-fluid.container.container-{breakpoint} 网格系统(Gird system)指定列宽实现8列布局 等列宽auto列宽响应式列 响应式工具类display属性其他工具类 组件按钮按钮组轮播图面…

还是搞不懂Anaconda是什么?读这一篇文章就够了

文章目录 1 Anaconda介绍2 conda介绍3 安装Anaconda4 Anaconda的使用配置Anaconda源 5 创建虚拟环境并使用5.1 创建虚拟环境5.2 查看所有环境5.3 激活环境5.4 安装包5.4.1 conda方式5.4.2 pip方式5.4.3 从Anaconda.org安装包 5.5 查看该环境的所有包5.6 测试是否安装成功 6 退出…

百分点科技蝉联中国数据治理解决方案市场第二

近日&#xff0c;IDC发布了《中国数据治理市场份额&#xff0c;2022》报告&#xff0c;报告显示&#xff0c;2022年中国数据治理解决方案市场相比2021年增长了7.4%&#xff0c;百分点科技仍然保持领先优势&#xff0c;蝉联数据治理解决方案市场第二。 中国数据治理市场是一个发…

win7 修改粘滞键绕过开机密码(实操步骤详解)

文章目录 win7 使用粘滞键绕过开机密码声明 win7 使用粘滞键绕过开机密码 趁现在还没完全启动关机断电 再次开机选择启动修复 取消系统还原&#xff0c;等待几分钟 查看隐私说明 进入记事本可以打开文件 打开文件可以在C盘修改系统文件 找到粘滞键程序修改名称 找到cm…

leetcode_第17题_缺失的第一个正数——原地哈希

题目 题目 分析 正常思路&#xff1a;另外制作一个哈希表&#xff0c;然后遍历就ok 但是这样不符合题目空间复杂度要求&#xff0c;所以采用原地哈希就可以了。 思路&#xff1a;把正常数字nums[i]交换存储到下标位置为nums[i]-1的地方&#xff0c;不正常数字不管。&#xff…

Rdkit|最大公共子结构

github&#xff1a;地址 文章目录 Rdkit|最大公共子结构rdFMCS.FindMCS参数bondCompareatomComparematchValencesringMatchesRingOnlycompleteRingsOnlymatchChiralTag 高亮分子的不同子结构参考 Rdkit|最大公共子结构 rdFMCS.FindMCS mols: 分子对象maximizeBonds一个结构由…

springboot 获取上传到minio服务器的文件大小

springboot 获取上传到minio服务器的文件大小 前言探究获取文件大小的方法实践及示例 前言 一般minio上传文件&#xff0c;会在上传时拿到文件大小&#xff0c;并保存在数据库中。若想直接从minio上获取&#xff0c;如何获取&#xff1f; 探究获取文件大小的方法 pom依赖 &l…

ubuntu安装nginx

1、apt-get安装nginx 1.1安装最好用root用户安装 不然很多文件权限的报错会让人崩溃 sudo su root apt-get install nginx nginx -v #查看安装版本 service nginx start #启动nginx 1.2查看网页&#xff0c;能看到nginx的页面 1.3核对nginx的文件 find / -name nginx 看…

【UE4 C++】02-编译、生成当前的C++程序

一、编译 编译快捷键&#xff1a; CtrlF7 如果不使用快捷键&#xff0c;可以点击顶部菜单栏中的下拉按钮&#xff0c;然后选择自定义 点击添加命令 点击“生成”&#xff0c;选择编译“”&#xff0c;点击“确定” 此时可以看到顶部菜单栏多了一个用于编译的按钮 二、生成 鼠…

目标百万尼特亮度,这家公司用激光背光提升XR显示技术

​亮度不足一直是AR/VR显示中想要解决的难题之一&#xff0c;目前的AR光源中有多种方案&#xff0c;比如Micro LED、LCoS、DLP等&#xff0c;尽管Micro LED在亮度等方面优势明显&#xff0c;但制造工艺还不成熟。总的来看&#xff0c;目前AR中高亮度解决方案还有很长一段路​要…

Build input file cannot be found: .pch

xcode真机运行时&#xff0c;报错&#xff1a;Build input file cannot be found: /Users/mac/Desktop/projects/xxx/xxx.pch 实际查看发现&#xff0c;项目中的.pch文件存在&#xff0c;但运行时报错。修改配置里的.pch文件路径后&#xff0c;正常。

聊聊用户故事与测试启发

这是鼎叔的第六十六篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。 用户故事的概念于1998年被正式提出&#xff0c;在2001年开始逐步成熟。目前&#xff0c;…