LeetCode/NowCoder-链表经典算法OJ练习3
孜孜不倦:孜孜:勤勉,不懈怠。指工作或学习勤奋不知疲倦。💓💓💓
目录
说在前面
题目一:返回倒数第k个节点
题目二:链表的回文结构
题目三:相交链表
SUMUP结尾
说在前面
dear朋友们大家好!💖💖💖数据结构的学习离不开刷题,在对链表的相关OJ进行练习后又更新复杂度的OJ,这并不意味这链表的题目就结束了,我们今天就继续联系链表相关的OJ练习。当今天我们的题目除了LeetCode,还来自NowCoder。
👇👇👇
友友们!🎉🎉🎉点击这里进入力扣leetcode学习🎉🎉🎉
以下是leetcode题库界面:
👇👇👇
🎉🎉🎉点击这里进入牛客网NowCoder刷题学习🎉🎉🎉
以下是NowCoder题库界面:
题目一:返回倒数第k个节点
题目链接:面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)
题目描述:
题目分析:
思路1:将创建一个数组temp,将链表中节点的地址存入数组temp,再返回数组中下标为n-k的地址所指向的数据。
举例:1->2->3->4->5->6 和 k = 3
代码如下:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
#define numsSize 100
typedef struct ListNode ListNode;
int kthToLast(struct ListNode* head, int k) {ListNode* pcur = head;ListNode* temp[numsSize];//创建临时数组int i = 0;while (pcur != NULL)//将链表节点地址存入数组temp{temp[i++] = pcur;pcur = pcur->next;}return temp[i - k]->val;//返回倒数第k个节点的数据
}
不过,假设链表很长,此时空间复杂度就会比较高,所以用numsSize固定长度显然不是好的办法,应该用动态内存分配的办法来初始化temp
代码如下:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
int kthToLast(struct ListNode* head, int k) {ListNode* pcur = head;int length = 0;while (pcur != NULL)//遍历数组,得到节点的个数{length++;pcur = pcur->next;}//动态创建二级指针变量tempListNode** temp = (ListNode**)malloc(length * sizeof(ListNode*));pcur = head;int i = 0;while (pcur != NULL)//将链表节点地址存入temp{temp[i++] = pcur;pcur = pcur->next;}return temp[i - k]->val;//返回倒数第k个节点的数据
}
不过显然空间复杂度为O(N),不是一个非常好的办法。如果给出前提条件:空间复杂度为O(1),这个方法就不行了。
思路2:将创快慢指针法:定义快慢指针fast、slow,先让fast走k步,再让slow和fast同时走,这样当fast走完slow刚好指向倒数第k个节点。
举例:1->2->3->4->5->6 和 k = 3
代码如下:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
int kthToLast(struct ListNode* head, int k) {//定义快慢指针ListNode* slow = head;ListNode* fast = head;while (k--)//让fast先走k步{fast = fast->next;}//当fast走完,此时slow指向的就是倒数第k个节点while (fast != NULL){fast = fast->next;slow = slow->next;}return slow->val;
}
题目二:链表的回文结构
题目链接:链表的回文结构_牛客题霸_牛客网 (nowcoder.com)
题目描述:
题目分析:
思路:先找到链表的中间节点,再将链表的后半部分反转,比较前半部分和后半部分的元素是否相等。
我们需要用到之前OJ练习1中的两个函数:
1.链表的中间节点:876. 链表的中间结点 - 力扣(LeetCode)
2.反转链表:206. 反转链表 - 力扣(LeetCode)
如果忘记了,大家点击这里复习:LeetCode/NowCoder-链表经典算法OJ练习1
代码如下:
/*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;struct ListNode* fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;}//反转链表struct ListNode* reverseList(struct ListNode* head) {if (head == NULL)return NULL;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;}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;A = A->next;}return true;}
};
像这种题属于组合体,比较综合,同时也告诉我们具有一定功能的代码在下次使用时可以稍加修改再Ctrl+C/V,可以省去很多麻烦,也比较方便。
题目三:相交链表
题目链接:160. 相交链表 - 力扣(LeetCode)
题目描述:
题目分析:
思路:这题比较复杂,我们需要模块化思考。同时注意单链表相交为"Y"型而不可能为"X"型,因为单链表没有两个next指针。
1、如何判断相交?
判断尾指针,如果尾指针地址相同则相交(注意,不能用尾节点所存储的值是否相同判断,因为之前有可能也有节点存储了和尾节点相同的值)。
2、若相交,如何找出第一个交点?
思路1:A链表的节点依次和B链表的所有节点比较,A的某个节点和B链表的某个节点相等,则这个节点就是交点。
代码如下:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {ListNode* cur1 = headA;ListNode* cur2 = headB;//让A、B链表都走到尾节点while(cur1->next){cur1 = cur1->next;}while(cur2->next){cur2 = cur2->next;}if(cur1 != cur2)//判断尾节点是否相等return NULL;cur1 = headA;while(cur1->next)//让A中每个节点都和B中的所有节点比较{cur2 = headB;while(cur2->next){if(cur1 == cur2)//第一个相等的就是交点return cur2;cur2 = cur2->next;}cur1 = cur1->next;} return cur2;
}
这个方法的时间复杂度为O(N^2)。
思路2:分别计算出链表A、B的长度,让长的先走差距的步数,然后再让两链表同时开始走,第一个相等的就是交点。
代码如下:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {ListNode* cur1 = headA, * cur2 = headB;int lenA = 0;int lenB = 0;while (cur1->next)//统计链表A的长度{lenA++;cur1 = cur1->next;}while (cur2->next)//统计链表B的长度{lenB++;cur2 = cur2->next;}if (cur1 != cur2)//判断是否有交点return NULL;//假设法,设置长短链表ListNode* LongList = headA, * ShortList = headB;if (lenA < lenB){LongList = headB;ShortList = headA;}int gap = abs(lenA - lenB);//两链表节点差值while (gap--)//让长的先走差值的步数{LongList = LongList->next;}while (LongList != ShortList)//让两链表一起走,第一个相等的就是交点{LongList = LongList->next;ShortList = ShortList->next;}return LongList;
}
这个方法的时间复杂度为O(N)。
对比两种解法,显然第二种方法是更好的。
SUMUP结尾
数据结构就像数学题,需要刷题才能对它有感觉。之后还会更新数据结构相关的练习题、面试题,希望大家一起学习,共同进步~
如果大家觉得有帮助,麻烦大家点点赞,如果有错误的地方也欢迎大家指出~
相关文章:

LeetCode/NowCoder-链表经典算法OJ练习3
孜孜不倦:孜孜:勤勉,不懈怠。指工作或学习勤奋不知疲倦。💓💓💓 目录 说在前面 题目一:返回倒数第k个节点 题目二:链表的回文结构 题目三:相交链表 SUMUP结尾 说在前…...

如何理解HTML语义化
如何理解HTML语义化 HTML语义化,简单来说,就是使用HTML标签来清晰地表达页面内容的结构和意义,而不仅仅是作为布局的容器。它强调使用具有明确含义的HTML标签来描述页面元素,而不是仅仅依赖CSS来实现页面的外观和布局。 理解HTM…...

Solved problem: The number of elements in the character array
Problem: 未解决的问题:字符数组中元素的个数-CSDN博客 Solution: Add \0 at the end of the character array More detailed content can be found in the link below. Sizeof and Length of character array-CSDN博客...

Flume Channels简介及官方用例
通道是在代理上暂存事件的存储库。Source 添加事件,Sink 将其删除。 1、Memory Channel 事件存储在具有可配置最大大小的内存中队列中。它非常适合需要更高吞吐量的流,但在agent发生故障时会丢失暂存数据 Property Name Default Description type …...

【AI】如何用非Docker方法安装类GPT WebUI
【背景】 本地LLM通信的能力需要做成局域网SAAS服务才能方便所有人使用。所以需要安装WebUI,这样既有了用户界面,又做成了SAAS服务,很理想。 【问题】 文档基本首推都是Docker安装,虽然很多人都觉得容器多么多么方便࿰…...

2024年ai知识库:特点、应用与搭建
随着科技的进步和企业的需要,ai知识库逐渐走进大众的视野并深受企业的青睐,掀起了搭建ai知识库的热潮。LookLook同学就来简单介绍一下关于ai知识库的特点、应用与发展趋势,带你了解2024年的ai知识库。 一、ai知识库的定义与特点 ai知识库是结…...

查询一个字符串在另一个字符串中出现的次数(java)
查询一个字符串在另一个字符串中出现的次数 例: String str1“helloworld,java,python,hellokafka,world big table helloteacher”; String str2“hello”; 字符串str2在str1中出现3次 代码 package exercise.test8;public class Demo8 {public static void mai…...

Docker in Docker 原理与实战
一、引言 随着容器化技术的普及,Docker 作为一种主流的容器管理工具,已被广泛应用于开发、测试及生产环境中。Docker 的灵活性和便捷性使得它成为 DevOps 流程中不可或缺的一部分。然而,在一些复杂的应用场景中,我们可能需要在一…...

Rust学习心得
我分享一下一年的Rust学习经历,从书到代码都一网打尽。 关于新手如何学习Rust,我之前在Hacker News上看到了这么一篇教程: 这篇教程与其他教程不同的时,他不是一个速成教程,而是通过自己的学习经历,向需要…...

K8s deployment 进阶
文章目录 K8s deployment 进阶Deployment 更新策略RecreateRollingUpdatemaxSurge 和 maxUnavailable minReadySecondsprogressDeadlineSeconds Deployment 版本回滚Deployment 实现灰度发布 K8s deployment 进阶 Deployment 更新策略 Recreate 重建 (Recreate)&…...

python实现二叉搜索树(AVL树)简单样例
一、二叉搜索树 class TreeNode:def __init__(self, value):self.value valueself.left Noneself.right Noneclass BinarySearchTree:def __init__(self):self.root Nonedef insert(self, value):if self.root is None:self.root TreeNode(value)else:self._insert(self.…...

Day47 打家劫舍123
198 打家劫舍 题目链接:198.打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,…...

OceanBase 开源社区新进展|obdiag SIG成立
为了构建完善的 OceanBase 诊断生态系统,汇聚各方力量,形成涵盖工具、知识在内的全方位诊断生态体系,助力开发者更高效地驾驭 OceanBase,OceanBase 社区宣布成立诊断 SIG,名称:obdiag SIG。 详情参加原文链…...

React类组件生命周期详解
在React的类组件中,从组件创建到组件被挂载到页面中,这个过程react存在一系列的生命周期函数,最主要的生命周期函数是componentDidMount、componentDidUpdate、componentWillUnmount 生命周期图例如下 1. componentDidMount组件挂载 如果你…...

智能车竞赛指南:从零到一,驶向自动驾驶的未来
智能车竞赛指南:从零到一,驶向自动驾驶的未来 一、智能车竞赛概览1.1 竞赛介绍1.2 竞赛分类 二、智能车开发技术基础2.1 硬件平台2.2 软件开发 三、实战案例:循线小车开发3.1 系统架构3.2 代码示例 四、技术项目:基于ROS的视觉导航…...

微服务项目收获和总结---第2,3天(分库分表思想,文章业务)
①分库分表思想 文章表一对一为什么要拆分?因为文章的内容会非常大,查询效率会很低,我们经常操作文章的基本信息,不会很经常查询文章内容。充分发挥高频数据的操作效率。 ②freemarker和minIO 由于文章内容数据量过大,…...

【全网最全】2024电工杯数学建模A题21页初步参考论文+py代码+保奖思路等(后续会更新)
您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片链接,那是获取资料的入口! 【全网最全】2024电工杯数学建模A题21页初步参考论文py代码保奖思路等(后续会更新成品论文)「首先来看看目前已有的资料&#x…...

怎么通过OpenAI API调用其多模态大模型(GPT-4o)
现在只要有额度,大家都可以调用OpenAI的多模态大模型了,例如GPT-4o和GPT-4 Turbo,我一年多前总结过一些OpenAI API的用法,发现现在稍微更新了一下。主要参考了这里:https://platform.openai.com/docs/guides/vision 其…...

自定义文字线性
...

robosuite导入自定义机器人
目录 目的:案例一:成果展示具体步骤:URDF文件准备xml文件生成xml修改机器人构建 目的: 实现其他标准/非标准机器人的构建 案例一: 成果展示 添加机器人JAKA ZU 7 这个模型 具体步骤: URDF文件准备 从…...

四天学会JS高阶(学好vue的关键)——构造函数数据常用函数(理论+实战)(第二天)
一、对象创建引发构造函数产生 1.1 创建对象三种方式: 利用对象字面量创建对象 const obj {name: 佩奇}注:对象字面量的由来:即它是直接由字面形式(由源代码直接)创建出来的对象,而不是通过构造函数或者…...

【Linux学习】进程地址空间与写时拷贝
文章目录 Linux进程内存布局图:内存布局的验证 进程地址空间写时拷贝 Linux进程内存布局图: 地址空间的范围,在32位机器上是2^32比特位,也就是[0,4G]。 内存布局的验证 代码验证内存布局: 验证代码: #include<s…...

Git远程控制
文章目录 1. 创建仓库1.1 Readme1.2 Issue1.3 Pull request 2. 远程仓库克隆3. 推送远程仓库4. 拉取远程仓库5. 配置Git.gitignore配置别名 使用GitHub可以,采用Gitee也行 1. 创建仓库 1.1 Readme Readme文件相当于这个仓库的说明书,gitee会初始化2两份…...

怎样从SQL中分析和提取访问的字段信息?| OceanBase实践
当执行任意一条SELECT SQL语句时,我们如何能够分析出所访问的字段信息,并进一步判断结果集中的每一列数据具体来自于哪些数据库、表以及表中的哪些字段呢?本文将会详细阐述针对此问题的技术解决方案。 应用场景 从 SQL 中解析访问的原始字段…...

MySQL 服务无法启动
常见原因: 检查端口占用: 使用命令行工具(如netstat)来检查3306端口是否已被其他程序占用,输入netstat -ano(Windows)或netstat -tulnp | grep 3306(Linux/Mac)来查找3306端口的占用情况。如果…...

Python贪心算法
贪心算法(Greedy Algorithm)是一种常见的算法设计策略,它在每一步选择当前最优解,希望通过局部最优解最终得到全局最优解。贪心算法通常适用于满足一些特定条件的问题,例如货币找零、活动选择、任务调度等。贪心算法的…...

牛客网刷题 | BC85 牛牛学数列3
目前主要分为三个专栏,后续还会添加: 专栏如下: C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读! 初来乍到,如有错误请指出,感谢! 描述 牛牛准备继续进阶&…...

quartz定时任务
Quartz 数据结构 quartz采用完全二叉树:除了最后一层每一层节点都是满的,而且最后一层靠左排列。 二叉树节点个数规则:每层从左开始,第一层只有一个,就是2的0次幂,第二层两个就是2的1次幂,第三…...

Python基础学习笔记(五)——选择结构与循环结构
目录 程序的组织结构条件选择结构1. 单分支结构2. 双分支结构3. 多分支结构4. 嵌套(分支)结构5. 无内容执行6. 条件表达式 循环结构1. 可迭代对象2. range()函数3. for循环语句4. while循环语句5. 结束语句 程序的组织结构 程序的组织结构主要有以下三种…...

Vue插槽solt如何传递具名插槽的数据给子组件?
在Vue中,你可以通过作用域插槽(scoped slots)来传递数据给子组件。这同样适用于具名插槽。首先,你需要在子组件中定义一个具名插槽,并通过v-slot指令传递数据。例如: 子组件(ChildComponent.vu…...