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

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

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

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


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

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

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

        常见的一种判断链表是否带环的错误方法:某节点的next指针和遍历的pcur的next指针相同,就认为该链表带环。这是错误的!!! 因为我们不知道遍历的pcur指针是否进环,他可能在环外,也可能在环内。

最好的办法就是使用快慢指针追击:慢指针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 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

三、力扣---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三连支持一下叭! 

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

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

相关文章

Web前端开发 小实训(三) 商品秒杀小练习

学生能够在本次实训中完成商品秒杀页面的基本逻辑 任务要求 能够实现某一个商品的秒杀&#xff0c;在倒计时结束后不再进行秒杀。 操作步骤 1、打开预设好的页面 <html><head><meta charset"utf-8"><title>秒杀</title><link …

vue + element-plus 开发中遇到的问题

1.问题之路由守卫 初写路由守卫&#xff0c;对于next()的理解不是很透彻&#xff0c;就想着都放行&#xff0c;不然看不到效果&#xff0c;结果控制台出现了警告&#xff0c;想着报黄的问题就不是问题&#xff0c;但仔细一看发现他说&#xff0c;如果再生产阶段就会失败&#x…

【问题分析】锁屏界面调起google语音助手后壁纸不可见【Android 14】

1 问题描述 为系统和锁屏分别设置两张不同的壁纸&#xff0c;然后在锁屏界面长按Power调起google语音助手后&#xff0c;有时候会出现壁纸不可见的情况&#xff0c;如以下截图所示&#xff1a; 有的时候又是正常的&#xff0c;但显示的也是系统壁纸&#xff0c;并非是锁屏壁纸…

【用文本生成歌声】Learn2Sing 2.0——歌声转换算法及梅尔频谱详解

一. 频谱图与梅尔谱图的介绍 频谱图&#xff1a;频谱图可以理解为一堆垂直堆叠在一起的快速傅里叶变换结果。 1.1 信号 在进入频谱图模块之前&#xff0c;首先我们需要了解信号是什么。 信号就是某一特定量随时间变化&#xff0c;对于音频来说&#xff0c;这个特定的变化量就…

韩顺平0基础学Java——第8天

p155-168 数组&#xff08;第六章&#xff09; 数组可以存放多个同一类型的数据&#xff0c;数组也是一种数据类型&#xff08;引用类型&#xff09;。 即&#xff0c;数组就是一组数据~ 例&#xff1a;double [] hens {1,2,3,4,5,6}; 新建了一组鸡&#xff0c;里面有6个。…

代码随想录算法训练营第36期DAY18

DAY18 二叉树的层序遍历 102二叉树的层序遍历 “队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。” 二叉树层序遍历模版&#xff1a; /** * Definition for a binary tree node. * struct TreeNode { *…

PostgreSQL的学习心得和知识总结(一百四十二)|深入理解PostgreSQL数据库数据库之 Continuous Integration

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

办公技巧之合集文档 拆分_word

问题 如何将文档合集拆分为单独文档。 操作步骤 软件 word 365 原理简述&#xff1a; 在 word 大纲视图下&#xff0c;通过一级标题确定子文档范围&#xff0c;然后导出即可。 文档结构 从下图可见&#xff0c;文档结构为已建立大纲级别的文档&#xff0c;如果没有建立&a…

每日一题——力扣27. 移除元素(举一反三)

题目链接&#xff1a;https://leetcode.cn/problems/remove-element/description/ 菜鸡写法&#xff1a; // 函数定义&#xff0c;移除数组nums中所有值为val的元素&#xff0c;并返回新的数组长度 int removeElement(int* nums, int numsSize, int val) {// 如果数组长度为…

Steam游戏搬砖,不说破万,月入5K没问题

steam游戏搬砖项目的玩法就是打汇率差&#xff0c;在steam平台购买道具&#xff0c;挂在网易buff上出售&#xff0c;通过汇率差盈利。一天交易几百美金的道具&#xff0c;大概能搞到200块左右的利润&#xff0c;而且平台是支持这样交易的&#xff0c;还很稳定。目前最主流的游戏…

设计模式1——初步认识篇

设计模式1——初步认识篇 一、先让我们浅聊一下面向对象和设计模式。 说起设计模式&#xff0c;我第一次听到它&#xff0c;是在学习面向对象的时候。那么什么是面向对象&#xff0c;什么是设计模式&#xff0c;而且设计模式和面向对象又有什么关系呢&#xff1f; 1、什么是面…

im8mm 网络卡死 Rx packets:1037578 errors:66 dropped:0 overruns:66 frame:0

1&#xff1a;网络接收数据包异常 2&#xff1a;问题复现 问题在进行网络数据包同吞吐量测试的时候出现的。同时发现&#xff0c;在使用iperf2测试时&#xff0c;是不会出现网络中断卡死的情况&#xff0c;使用 iperf3时才会出现此问题 指令(下面的指令运行在PC2上面&#xff…

十二种网络威胁防护方案

一、SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服务器执行非授权的任…

kali linux更新卡在libc6:amd64 (2.37-15)

适配于linux的windows子系统,wsl2,安装kali linux,运行 sudo apt update 卡在:Setting up libc6:amd64 (2.37-15) … 关机重启、重新修复执行也不行 解决办法:kill当前apt进程或者关机重启kali-linux,然后执行: ssudo mv /usr/sbin/telinit /usr/sbin/telinit.baksu…

安装docker镜像nginx1.26.0版本,与删除docker容器【灵异事件】

为了http3 的这个模块&#xff0c;所以需要升级nginx的版本&#xff0c;需要nginx1.26.0才有 –with-http_v3_module 这个模块 为什么记录一下&#xff1f;因为觉得奇怪 1&#xff1a;删除nginx镜像&#xff0c;显示镜像还被某个容器在使用 luichunluichun:~$ docker rmi ng…

数电——集成计数器

分析 &#xff08;1&#xff09;74161 4位同步&#xff08;cp相同&#xff09;二进制&#xff0c;模16&#xff08;2的4次方&#xff09; 逻辑符号 端口 D0,D1,D2,D3为输入信号 Q0,Q1,Q2,Q3为输出信号 RCO输出进位标志&#xff1a;记满16个数后&#xff0c;输出1 P,T 控…

番外篇 | 利用PyQt5+YOLOv5来搭建目标检测系统(附可视化界面+功能介绍+源代码)

前言:Hello大家好,我是小哥谈。PyQt5是一个Python绑定的Qt库,是用于创建图形用户界面(GUI)和其他应用程序组件的工具包。PyQt5提供了许多GUI元素,如按钮、文本框、标签等,也提供了许多Qt的功能,如网络、数据库、XML等。通过PyQt5可以在Python中使用Qt的丰富功能和强大的工…

远程桌面连接不上怎么连服务器,原因是什么?如何解决?

远程桌面连接不上怎么连服务器&#xff0c;原因是什么&#xff1f;如何解决&#xff1f; 面对远程桌面连接不上的困境&#xff0c;我们有办法&#xff01; 当你尝试通过远程桌面连接服务器&#xff0c;但遭遇连接失败的挫折时&#xff0c;不要慌张。这种情况可能由多种原因引起…

Python运维之协程

目录 一、定义协程 二、并发 三、异步请求 协程是一种轻量级的线程&#xff0c;它通过保存和恢复寄存器上下文和栈来实现调度切换&#xff0c;从而保留函数执行的状态。 这种机制使得协程在处理I/O密集型任务时效率较高&#xff0c;因为它们可以在I/O操作期间让出CPU&#…

【触摸案例-手势解锁案例-错误的样式 Objective-C语言】

一、然后呢,我们再来说一下这个错误的样式 1.首先,在我们的示例程序里边,我现在来连一条线,一撒手的时候, 它先出来一个,红色的按钮的样式,那么这个时候呢,实际上,是在设置另外一种状态,给按钮的另外一种状态,再去设置另外一张红色的图片,然后呢,再去切换成那一种…