LeetCode/NowCoder-链表经典算法OJ练习3

news2024/12/24 9:09:36

  孜孜不倦:孜孜:勤勉,不懈怠。指工作或学习勤奋不知疲倦。💓💓💓

目录

说在前面

题目一:返回倒数第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;
    }
    //动态创建二级指针变量temp
    ListNode** 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结尾

数据结构就像数学题,需要刷题才能对它有感觉。之后还会更新数据结构相关的练习题、面试题,希望大家一起学习,共同进步~

如果大家觉得有帮助,麻烦大家点点赞,如果有错误的地方也欢迎大家指出~

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

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

相关文章

分布式锁2-Zookeeper分布式锁实战

Zookeeper分布式锁实战 使用curator操作Zookeeper进行实战&#xff1b; curator是什么&#xff1a;Apache Curator包含一套高级API框架和工具类&#xff0c;它 是Apache ZooKeeper 的Java 客户端库。 准备 pom文件引入curtor依赖和zookeeper依赖 <!--curator--> <…

微信小程序开发环境的搭建

一、注册微信小程序账号 二、安装微信开发者工具 1.下载微信开发者工具。 官网下载地址&#xff1a;https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/downloads.html 2、选择稳定版Window64下载安装 3、下载完毕后&#xff0c;点击下一步安装 三、使用微信开发者工具…

linux---信号的捕捉和处理

提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、信号 可以简单理解为信号是一个进程给另一个信号发消息&#xff0c;进程收到对应的信号就执行对应的方法&#xff0c;linux信号可以分为实时信号和非实时信号 1-31为非实时信号&#xff0c;34-64为…

安全风险 - 检测Android设备系统是否已Root

在很多app中都禁止 root 后的手机使用相关app功能&#xff0c;这种场景在金融app、银行app更为常见一些&#xff1b;当然针对 root 后的手机&#xff0c;我们也可以做出风险提示&#xff0c;告知用户当前设备已 root &#xff0c;谨防风险&#xff01; 最近在安全检测中提出了一…

远动通讯屏柜的组成及各装置的作用

远动通讯屏柜的组成及各装置的作用 远动通讯屏是基于公共电网安全而投入的远方监控遥控设备&#xff1b;主要由远动装置、通讯管理机、交换机、调制解调器、GPS对时装置、数字通道防雷器、模拟通道防雷器、插线板、空气开关、屏柜及附件等设备组成、标配尺寸2260*800*600&…

Android App启动流程和源码详解

前言 之前看了些App启动流程的文章&#xff0c;但是看得很浅显&#xff0c;隔了没多久就忘了&#xff0c;自己抓耳挠腮的终于看完了&#xff0c;看得头疼哦。因为很多是个人理解&#xff0c;大哥们主打一个7分信&#xff0c;2分思考&#xff0c;1分怀疑哈。 主要看的源码是An…

Python中文件操作和异常处理

文章目录 一、文件操作1.概念2.文件3.二进制 二、基本文件操作三、乱码产生四、with open() as f五、代码实现文件复制粘贴六、try ... except ...七、代码比较 一、文件操作 1.概念 帮助我们把爬虫抓下来的数据&#xff0c;进行保存。 2.文件 在计算机中&#xff0c;没有p…

工业大模型带来智能生产新范式

在当前工业行业的发展背景下&#xff0c;大模型技术展现出广阔的应用前景&#xff0c;在提升专业知识的可获取性和传承、优化软件技术的应用、提高数据驱动决策的准确性和效率等方面拥有显著潜力。 ‍‍‍‍‍‍‍‍‍‍据了解&#xff0c;蓝卓“基于supOS工业操作系统的工业大…

【HCIP学习】STP协议

一、STP协议出现背景&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09; 二层环路带来的问题&#xff1a;广播风暴&#xff1b; MAC地址表的震荡&#xff1b; 二、STP定义 stp是二层网络中用于消除环路的协议&#xff0c;通过阻断冗余链路来消除&#xff…

ganglia的安装使用

1.集群内分别安装epel-release依赖&#xff0c;更新yum源 sudo yum -y install epel-release 2&#xff0e;各节点上分别安装gmond sudo yum -y install ganglia-gmond 3.监控节点上安装gmetad和web(这里安装在node1上) sudo yum -y install ganglia-gmetad sudo yum -y insta…

关于阳光雨露外派联想的面试感想

最近在找工作&#xff0c;接到了一个阳光雨露外派联想的面试邀请。说实在的一开始就有不对劲的感觉。想必这就是大厂的自信吧&#xff0c;上就问能不能现场面试&#xff0c;然后直接发面试邀请。这时候我倒是没觉得有啥问题。 然后今天就去面试去了&#xff0c;住的比较偏&…

力扣HOT100 - 138. 随机链表的复制

解题思路&#xff1a; class Solution {public Node copyRandomList(Node head) {if(headnull) return null;Node p head;//第一步&#xff0c;在每个原节点后面创建一个新节点//1->1->2->2->3->3while(p!null) {Node newNode new Node(p.val);newNode.next …

jupyter notebook打开ipynb文件报错500

一开始能打开ipynb文件&#xff0c;但是内核挂掉了&#xff0c;显示如下图的报错 按照网上的教程卸载重装了jupyter 再启动jupyter notebook打开ipynb文件就报错500 网上教程说nbconvert要更新&#xff0c;重装之类的&#xff0c;我都试过了&#xff0c;仍然报错 最后安了个P…

1103 缘分数(测试点4)

solution 测试点4&#xff1a;1 1不符合缘分数定义&#xff0c;但是这个判断能够通过记得排除掉 #include<iostream> #include<cmath> using namespace std; bool judge(int n){int t sqrt(n);if(t * t n) return true;return false; } int main(){int n, m, c…

Deep Residual Learning for Image Recognition--论文笔记

论文笔记 论文来源&#xff1a; Deep Residual Learning for Image Recognition 代码来源 还没上传 1论文摘要的翻译 深度神经网络更难训练。我们提出了一个残差学习框架&#xff0c;以简化比以前使用的网络深度大得多的网络的训练。我们明确地将层重新表述为参考层输入的…

概念艺术3D三维虚拟展览系统让更多人一同领略艺术的无穷魅力

经过多年的技术积累&#xff0c;华锐视点3D云展平台为各位提供的网上3D书画展厅&#xff0c;是一个集逼真视觉体验与沉浸式感官享受于一体的线上艺术殿堂。通过先进的Web3D实时渲染技术&#xff0c;打造全景3D立体场景&#xff0c;让您仿佛置身于实体展厅之中&#xff0c;感受那…

报名倒计时两周|2024 OpenTiny 开源之夏项目直播解读回顾

5月16日&#xff0c;OpenTiny 开源社区成功举办了以《OpenTiny 开源之夏项目解读直播》为主题的直播活动。此次直播中&#xff0c;华为云的高级前端工程师曾令卡、华为云的高级前端工程师伍其和与10位开源之夏技术专家携手组成项目导师团&#xff0c;面向广大开发者一同深入探讨…

QT加载CAD文件(一)QCAD

近期为了加载.dxf格式的文件简单学习了下QCAD和LibreCAD编译和二次开发&#xff0c;QCAD 是一个免费、开源的计算机辅助绘图二维工具, 目前开源的二维CAD有QCAD、LibreCAD等&#xff0c;LibreCAD可以说是QCAD的分支版本。 一、QCAD 官网网址&#xff1a;https://www.qcad.org…

spring boot整合j2cache 关闭二级缓存

我们整合了 j2cache 的项目启动 日志会输出 一级缓存 二级缓存 一级是 EhCacheProvider 二级是 SpringRedisProvider 如果 我们不想用二级缓存 在 j2cache.properties 中 加上 j2cache.12-cache-open配置 值为 true/false true是启用二级缓存 false 是不起用 默认 true 所以 …