DS:顺序表、单链表的相关OJ题训练(2)

news2024/11/25 14:22:12

欢迎各位来到 Harper.Lee 的学习世界!

博主主页传送门:Harper.Lee的博客主页

想要一起进步的uu欢迎来后台找我哦!


一、力扣--141. 环形链表

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

        常见环形链表有以下几种:(环形链表不清楚最后一个节点即尾节点在哪里的)。

       常见的判断链表是否带环的错误方法方法1. 判断遍历的指针的next指针是否为进环时的第一个节点指针。错误原因是:首先我们不清楚用来遍历的指针是否进环,此外,环外的部分很长也可能比较短,什么时候进环不能确定。方法2. 判断尾节点的next指针是否为空。错误原因:如果链表是带环的,我们并不能知道谁是最后一个节点,也可以说是带环链表没有尾节点。

最好的办法就是使用快慢指针追击:慢指针slow一次走一步,快指针fast一次走两步。当

bool hasCycle(struct ListNode *head) {
    struct ListNode* slow = head,*fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;//两个next
        if(slow == fast)
            return true;
    }
    return false;
}

Q1:为什么一定会相遇?

        假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。此时,两个指针每移动一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情况,因此:在满指针走到一圈之前,快指针肯定是可以追上慢指针的,即相遇。

Q2:快指针一次走3步,走4步,...n步行吗?

        根据分析可知,快慢指针的追击问题不在于两者一次走多少步,而在于快慢指针之间的速度差

分析过程图片:

Q3:有没有可能会错过,永远追不上?

分析过程图片: 

       所以答案是:一定会追上,一定能追上!

二、力扣--142. 环形链表 II

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

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *slow = head, *fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;//两个next(两步)

        //相遇:
        if(slow == fast)
        {
            struct ListNode* meet = slow;
            while(meet != head)
            {
                meet = meet->next;
                head = head->next;
            }

            return meet;
        }
    }
    return NULL;
}

三、力扣---02.02. 返回倒数第 k 个节点

思路一:创建一个新数组,在数组中寻找相应的数据,返回数据对应的下标。(空间复杂度高了)

思路二:第一遍遍历得出节点个数(n),如果要求找倒数第k个节点,就去找正数第n-k+1个节点,并返回该节点的值。

思路三(在思路二的基础上要求空间复杂度O(1),也就是只能遍历链表一遍):快慢指针法。fast先走k步,拉开差距,然后两个指针再同时移动。注意单链表是不能倒着走的。可以加一个判断:k小于等于链表长度。

int kthToLast(struct ListNode* head, int k){
    struct ListNode* fast = head,*slow = head;//均是从头节点开始
    ///快指针先走k步(或者k-1步)
    while(k--)
    {
        fast = fast->next;
    }
    while(fast)//快慢指针同时走,快指针先走到头
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow->val;
}

四、牛客--OR36 链表的回文结构

        题目描述:对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。如:1->2->2->1,返回true。

单链表有奇数个和偶数个两种情况:1、先查找中间节点;2、后半段逆置。

代码如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
//查找中间节点 
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* slow =head,*fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* cur = head;
    struct ListNode* newhead = NULL;

    while (cur)
    {
        struct ListNode* next =cur->next;
        //头插
        cur->next=newhead;
        newhead = cur;

        cur = next;
    }

    return newhead;
}
    bool chkPalindrome(ListNode* A) 
    {
        struct ListNode* mid = middleNode(A);//查找中间节点
        struct ListNode* rmid = reverseList(mid);//逆置后半段

        while(rmid && A)//有一个为空,就结束了,则都不为空进入循环
        {
            if(rmid->val!=A->val)
            return false;

            rmid = rmid->next;
        }

        return true;
    }
};

五、力扣--160. 相交链表

        题目描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交

 

         链表的相交的形式:不是X字型,而是Y字型, 因为单链表的一个节点只能有一个next指针。

         思路一:A链表逐个结点与B链表比较,如果存在相等,则就是相交结点(注:要比较指针而不能比较值,因为值是可以重复的)。
        具体过程分析:1. 判断两个链表是否相交:判断两个链表的尾指针是否相等,相等则两个链表相交,注意用地址来判断而不是值。2. 若相交,找出第一个交点:用暴力求解,链表A的节点依次和链表B的所有节点比较一遍(比较地址,而不是值),如果链表A的某个节点和链表B相等,则这个节点就是交点。 最坏情况:不相交,时间复杂度:O(m*n)(两个链表的长度)。

        思路二:长的链表往前走长度差到短链表开头,再同时走,直到相等就是相交点。    

        最坏的情况:最后一个才遇到交点。F(n)=3*N,时间复杂度O(N)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA = headA,*curB= headB;
    int lenA = 1,lenB = 1;//计算链表长度
    while(curA->next)
    {
        curA = curA->next;
        ++lenA;
    }

    while(curB->next)
    {
        curB = curB->next;
        ++lenB;
    }
    //尾节点不相等就是相交
    if(curA != curB)
    {
        return NULL;
    }
    //长链表先走差距步,两个链表再同时走,第一个相等就是交点
    //假设法:让逻辑更加简单
    int gap = abs(lenA - lenB);
    struct ListNode* longList = headA,*shortList = headB;
    if(lenB > lenA)
    {
        longList =headB;
        shortList= headA;
    }

    while(gap--)
    {
        longList = longList->next;
    }

    while(longList != shortList)
    {
        longList = longList->next;
        shortList = shortList->next;
    }
    return shortList;
}


创作不易,喜欢的uu三连支持一下叭! 

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

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

相关文章

Spring框架概述

目录 1. Spring框架的起源 2. Spring框架的构成 3. Spring的发展历程 4. Spring的开发环境 4.1. Maven安装与配置 (1)Maven的下载与安装 (2)配置Maven的环境变量 (3)本地仓库的配置 (4…

前端开发者必备:Nginx入门实战宝典,从部署到优化一网打尽

🔥 个人主页:空白诗 文章目录 引言 👋一、Nginx简介 📚二、常见的Web服务器架构 🌀📌 架构概述📌 Nginx的深入探讨 三、正向代理与反向代理 🔮📌 正向代理工作原理&#…

synchronized 使用及实现原理

synchronized 关键字 如何使用 synchronized 关键字的使用方式主要有下面 3 种: 修饰实例方法 修饰静态方法 修饰代码块 1、修饰实例方法 (锁当前对象实例) 给当前对象实例加锁,进入同步代码前要获得 当前对象实例的锁 。 …

【opencv】图像处理(二)

前文指引 一、使用到的图片 一、梯度计算 原始图片 img cv2.imread(circle.jpg)plt.imshow(img) plt.show()sobel算子 使用两个核 Gx [[-1,0,1], [-2,0,2], [-1,0,1]] Gy [[-1,-2,-1], [0,0,0], [1,2,1]] dst cv2.Sobel(src, ddepth, dx, dy, ksize) ddepth 深度 -1d…

添砖Java之路(其四)——面向对象的编程,类和对象

目录 前言: 面向对象的编程: this关键字: 构造方法: 前言: 其实中间我还有很多地方没有去讲,因为我觉得里面的很多东西和c/c差不太多,就比如逻辑运算,方法重载,以及数…

庙算兵棋推演AI开发初探(4-调用AI模型)

前面讲了如何开展编写规则脚本型Agent(智能体)的方法,现在探究一下如何调用知识型(一般而言的训练出的模型)智能体的方法。 这次调用的是庙算平台的demo(网址见图) 下载了“知识强化学习型”…

详解依赖注入的三种方法以及遇到问题的解决

各位大佬光临寒舍,希望各位能赏脸给个三连,谢谢各位大佬了!!! 目录 1.三种依赖注入的方法 1.属性注入 优点 缺点 2.构造方法注入 优点 缺点 3.Setter注入 优点 缺点 4.小结 2.依赖注入常见问题的解决 1…

全国防灾减灾日主题活动投稿我可算找对了投稿方法

作为一名社区公众人员,我深知对外信息宣传的重要性。特别是在全国防灾减灾日这样的特殊时刻,我们不仅要向居民普及防灾减灾知识,还要通过媒体将社区的活动和成果展示给更多人。然而,在投稿的过程中,我最初却遭遇了诸多挑战。 起初,我采用传统的邮箱投稿方式,将精心撰写的稿件发…

网页如何集成各社区征文活动

Helllo , 我是小恒 由于我需要腾讯云社区,稀土掘金以及CSDN的征文活动RSS,找了一下没发现,所以使用GET 请求接口对网页定时进行拉取清洗,甚至无意间做了一个简单的json格式API 最终网址:hub.liheng.work API:http://hub.liheng.wo…

ubuntu server 22.04.4 系统安装详细教程

本教程使用vmware workstation 17创建虚拟机进行安装演示,安装方式和真机安装没有区别。 1、下载镜像 下载ubuntu server版本系统镜像,官网下载地址:https://cn.ubuntu.com/download/server/step1 注意:自己下载时需要确认是否是…

向银行家应用程序添加日期

● 首先我们将下面图片上的时间更换成现在的时间 const now new Date(); const day now.getDate(); const month now.getMonth() 1; const year now.getFullYear(); const hour now.getHours(); const min now.getMinutes();labelDate.textContent ${day}/${month}/$…

从头开始学Spring—01Spring介绍和IOC容器思想

目录 1.Spring介绍 1.1Spring概述 1.2特性 1.3五大功能模块 2.IOC容器 2.1IOC思想 ①获取资源的传统方式 ②反转控制方式获取资源 ③DI 2.2IOC容器在Spring中的实现 ①BeanFactory ②ApplicationContext ③ApplicationContext的主要实现类 1.Spring介绍 1.1Sprin…

ASP.NET Web Api 如何使用 Swagger 管理 API

前言 Swagger 是一个开源的框架,支持 OpenAPI 规范,可以根据 API 规范自动生成美观的、易于浏览的 API 文档页面,包括请求参数、响应示例等信息,并且,Swagger UI 提供了一个交互式的界面,可以帮助我们快速…

本来还挺喜欢……

前阵子买了个天空星开发板,到手之后发觉不对劲。 之前我们玩玩开发板都是用的面包板的,就算是ESP那种比较宽的板子用两个面包板拼一下也勉强可以用。 但是天空星它的引脚是分为两组,每组有两排,如果我们还是直接使用面包板的话&a…

Pencils Protocol 提供层次化的 Staking,品牌升级不断

Pencils Protocol 是一个 Scroll 生态中的一个综合应用平台,在全新的品牌升级后(原为 Penpad),其在原有的 LaunchPad 的基础上,进一步向收益聚合器、RWA 等板块进行全新的拓展。目前,Pencils Protocol 生态的整体功能板块包括 Lau…

Kubernetes——两万字超细致集群搭建平台规划

目录 前言——常见的K8S安装部署方式 一、Kubernetes平台规划 1.单Master集群架构 2.多Master集群架构 二、集群规划 1.服务器硬件配置推荐 2.操作系统初始化 2.1关闭防火墙 2.2关闭SElinux 2.3关闭Swap 2.4添加Hosts 2.5调整内核参数 2.5同步时间 三、集群搭建…

【每日刷题】Day39

【每日刷题】Day39 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 622. 设计循环队列 - 力扣(LeetCode) 2. 387. 字符串中的第一个唯一字符 - …

C++类细节,反汇编,面试题02

文章目录 2. 虚函数vs纯虚函数3. 重写vs重载vs隐藏3.1. 为什么C可以重载? 4. struct vs union4.1. 为什么要内存对齐? 5. static作用6. 空类vs空结构体6.1. 八个默认函数:6.2. 为什么空类占用1字节 7. const作用7.1 指针常量vs常量指针vs常量…

k8s v1.20二进制部署

目录 一、环境准备 二、操作系统初始化配置 2.1.关闭防火墙 ​编辑 2.2.关闭selinux 2.3.关闭swap 2.4.根据规划设置主机名 2.5在master添加hosts 2.6.调整内核参数 2.7.时间同步 三、部署 docker引擎 3.1.所有 node 节点部署docker引擎 四、部署 etcd 集群 4.1.…

【云计算小知识】云管理的作用是什么?

云计算已经成为推动企业数字化转型,提升运营效率的重要力量。而在这个过程中,云管理作为确保云计算环境稳定、高效运行的关键环节,其作用愈发凸显。今天我们小编就给大家详细介绍一下云管理的作用是什么? 云管理的作用是什么&…