链表基础算法题

news2024/11/16 21:27:57

1 移除链表元素

. - 力扣(LeetCode)

该题的思路是创建一个新链表,然后遍历原链表,将不是要求移除的链表元素放到新链表中,最后返回创建的新链表 就能达到移除链表元素的作用了。

当然这只是一种做法,还有很多能够实现该功能的做法,我们尽量思考怎样写才能让我们的代码空间复杂度和时间复杂度都更小。

typedef struct ListNode ListNode ;
ListNode* removeElements(ListNode* head, int val)
{
	//创建新链表
	ListNode* newhead,*newtail;
	newhead = newtail = NULL;
	//遍历原链表
	ListNode* pcur = head;
	while (pcur != NULL)
	{
		if (pcur->val != val)
		{
			//链表为空
			if (newhead == NULL)
			{
				newhead = newtail = pcur;
			}
			//链表不为空
			else
			{
				newtail->next = pcur;
				newtail = newtail->next;
			}
		}
		
		pcur = pcur->next;
	}
	if (newhead)
	    newtail->next = NULL;
	return newhead;
}

2.反转链表

. - 力扣(LeetCode)

在该题中,一个比较巧妙的方法是创建三个指针n1,n2,n3,n1初始化为空,n2初始化为头节点,n3为头结点的下一个节点,让中间指针n2从头开始遍历,把n2节点的next指针修改为指向n1,这样就能达到反转链表的效果了。

typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) 
{
	if (head == NULL)
	{
		return NULL;
	}
	ListNode* n1, * n2, * n3,*pcur;
	n1 = NULL;
	n2 = head;
	n3 = n2->next;
	while (n2)
	{
		n2->next = n1;
		n1 = n2;
		n2 = n3;
		if (n3)
			n3 = n3->next;
	}
	return n1;
}

3.链表的中间节点

. - 力扣(LeetCode)

在该题中,我们使用链表中常用的一种技术 -- 快慢指针。定义两个指针,慢指针一次走一步,快指针一次走两步,当快指针为空或快指针的下一个节点为空时停止,这是慢指针就是我们要找的中间节点。需要注意的是while循环的条件,fast和fast->next的位置不能交换,因为如果链表节点数为偶数,那么fast最后会指向NULL,而fast->next会报错。

typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) 
{
	ListNode* slow, * fast;
	slow = fast = head;
	while (fast && fast->next)//此处fast和fast->next位置不能交换
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}

4.合并连两个有序链表

. - 力扣(LeetCode)

该题的思路是:创建一个新链表,定义一个头指针newhead一个尾指针newtail,遍历比较所给的两个链表并比较它们的值,如果list1的值小于list2的值,则将新链表尾指针newltail指向list1,newtail和list1再指向下一个节点,反之操作list2。遍历完其中一个链表之后,将newtail直接指向另一个链表。当然,如果所给的两个链表其中一个链表为空,则直接返回另一个链表,如果两个链表都为空,返回另一个链表也就是返回空。

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
	if (list1 == NULL)
	{
		return list2;
	}
	if (list2 == NULL)
	{
		return list1;
	}

	ListNode* newhead, * newtail;
	newhead = newtail = (ListNode*)malloc(sizeof(ListNode));
	ListNode* l1 = list1;
	ListNode* l2 = list2;
	while (l1 && l2)
	{
		if (l1->val < l2->val)
		{

			newtail->next = l1;
			newtail = newtail->next;
			l1 = l1->next;
		}
		else
		{

			newtail->next = l2;
			newtail = newtail->next;
			l2 = l2->next;
		}
	}
	if (l1)
	{
		newtail->next = l1;
	}
	if (l2)
	{
		newtail->next = l2;
	}
	ListNode* ret = newhead->next;
	free(newhead);
	newhead = NULL;
	return ret;
}

5.链表分割

链表分割_牛客题霸_牛客网

该题的思路是:创建两个链表,遍历所链表,将值小于x的节点放到链表LessHead中,大的放到链表GeaterHead中。

   typedef struct ListNode ListNode;
ListNode* partition(ListNode* pHead, int x) 
{
	ListNode* LessHead, * LessTail;
	LessHead = LessTail = (ListNode*)malloc(sizeof(ListNode));
	ListNode* GeaterHead, * GeaterTail;
	GeaterHead = GeaterTail = (ListNode*)malloc(sizeof(ListNode));

	ListNode* pcur = pHead;
	while (pcur)
	{
		if (pcur->val < x)
		{
			LessTail->next = pcur;
			LessTail = LessTail->next;
			pcur = pcur->next;
		}
		else
		{
			GeaterTail->next = pcur;
			GeaterTail = GeaterTail->next;
			pcur = pcur->next;
		}
	}
	LessTail->next = GeaterHead->next;
	ListNode* ret = LessHead->next;
    GeaterTail->next = NULL;
	free(LessHead);
	LessHead = NULL;
	free(GeaterHead);
	GeaterHead = NULL;
	return ret;
}

6.链表的回文结构

链表的回文结构_牛客题霸_牛客网

做该题的一个思路是:先使用快慢指针找到所给链表的中间元素,然后以中间元素为头节点定义三个指针反转链表,最后左右同时开始遍历判断链表是否为回文结构。 

ListNode* findMiddle(ListNode* phead)
{
	ListNode* slow, * fast;
	slow = phead;
	fast = phead;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}
ListNode* reverseListNode(ListNode* phead)
{
	ListNode* n1, * n2, * n3;
	n1 = NULL;
	n2 = phead;
	n3 = n2->next;
	while (n2)
	{
		n2->next = n1;
		n1 = n2;
		n2 = n3;
		if (n3)
			n3 = n3->next;
	}
	return n1;
}
bool chkPalindrome(ListNode* A) 
{
	//1.找中间节点
	ListNode* mid = findMiddle(A);
	//2.反转链表
	ListNode* right = reverseListNode(mid);
	ListNode* left = A;
	while (right)
	{
		if (left->val != right->val)
		{
			return false;
		}
		left = left->next;
		right = right->next;
	}
	return true;

}

 

7.相交链表

. - 力扣(LeetCode)

 

该题的一个方法是:首先定义两个指针分别遍历给出的两个链表,并计算这两个链表的大小,如果这两个链表的最后一个节点相同,那么这两个链表一定相交,不相等则不相交,返回空,如果相交,则定义一个指向长链表的指针,一个指向短链表的指针,并通过代码中的方法确定那个是长链表哪个是短链表,并使长链表提前走几步(长短链表长度之间的差值),使两个指针遍历的长度相同,最后找到两个链表开始相交的节点。

typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
	ListNode* pheadA = headA;
	ListNode* pheadB = headB;
	int sizeA = 0;
	int sizeB = 0;
	while (pheadA->next)
	{
		pheadA = pheadA->next;
		sizeA++;
	}
	while (pheadB->next)
	{
		pheadB = pheadB->next;
		sizeB++;
	}
	if (pheadA != pheadB)
	{
		return NULL;
	}
	else
	{
		int gap = abs(sizeA - sizeB);
		ListNode* longList = headA;
		ListNode* shortList = headB;
		if (sizeA < sizeB)
		{
			longList = headB;
			shortList = headA;
		}
		while (gap--)
		{
			longList = longList->next;
		}


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

	}
}

8.环形链表1

. - 力扣(LeetCode)

该题的方法是:定义快慢指针,遍历链表,如果该链表是环形链表,则快指针会追赶上慢指针,不是环形链表,快指针会指向空,值得一提的是,如果莲表是环形链表,无论快指针每次走两步还是三步都一定能与慢指针相等,用数学方法可以证明,感兴趣的朋友可以尝试证明一下。

typedef struct ListNode ListNode;
bool hasCycle(struct ListNode* head) {
	ListNode* slow, * fast;;
	slow = fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		int n = 3;
		while (n--)
		{
			if (fast->next)
			{
				fast = fast->next;
			}
			else
			{
				return false;
			}
		}
		if (slow == fast)
		{
			return true;
		}
	}
    return false;
}

9.环形链表2

. - 力扣(LeetCode)

该题先通过快慢指针找到相遇点,再定义⼀个指针从链表起始位置运行,⼀个指针从相遇点位置绕环,每次都走⼀步,两个指针最终会在入口点的位置相遇 。该结论也是可以通过数学方法证明两个指针一定会在入口点的位置相遇。

typedef struct ListNode ListNode;
struct ListNode* detectCycle(struct ListNode* head) 
{
	ListNode* slow, * fast;
	slow = fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
		if (slow == fast)
		{
			ListNode* pcur = head;
			while (pcur != slow)
			{
				slow = slow->next;
				pcur = pcur->next;
			}
			return slow;
		}
	}
	return NULL;	
}

更多链表算法刷题链接:

牛客网:https://www.nowcoder.com/exam/oj

LeetCode:https://leetcode.cn/problems/copy-list-with-random-pointer/description/

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

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

相关文章

HarmonyOS 开发

环境 下载IDE 代码 import { hilog } from kit.PerformanceAnalysisKit; import testNapi from libentry.so; import { router } from kit.ArkUI; import { common, Want } from kit.AbilityKit;Entry Component struct Index {State message: string Hello HarmonyOS!;p…

Java蛋糕店烘焙店系统小程序系统源码

解锁烘焙新纪元&#xff0c;揭秘“蛋糕店烘焙店系统”的甜蜜秘籍&#xff01; &#x1f31f;【开篇&#xff1a;烘焙业的数字化浪潮】&#x1f31f; 在这个快节奏的时代&#xff0c;传统烘焙行业也迎来了它的数字化转型时刻&#xff01;你是否梦想过拥有一家高效运转、顾客满…

了解 JavaScript 中的请求 API

你准备好提升你的网络开发技能了吗&#xff1f;&#x1f680; 在当今数据驱动的世界中&#xff0c;了解如何从 API 获取和处理数据至关重要。本指南将引导您了解在 JavaScript 中发出 HTTP 请求的最新和最有效的方法&#xff0c;确保您的 Web 应用程序保持动态和前沿。 为什么请…

排序算法【冒泡排序】

一、原理 冒泡排序的原理比较简单&#xff0c;就是将待排序区域的数值挨个向后对比&#xff0c;直到比较到已排序的边界&#xff0c;就纳入已排序区域。 二、代码如下所示&#xff1a; #include <stdio.h> #include "test.h"/* 冒泡排序 */ void bubble_sort(…

【GH】【EXCEL】P2: Read DATA SET from EXCEL into GH

文章目录 ReadRead DataExcel Data sourceGH process and components instructionRead Data Read Data LiveLive Worksheet Read Read Data Excel Data source GH process and components instruction Read Data Read data from Excel Input parameters: Worksheet (Generic …

超网和无类间路由是什么?

​一、超网概述 超网是将多个连续的网络地址组合成一个增加的网络地址的技术。常用于减少路由器的路由表大小&#xff0c;网络的可扩展性。通过合并连续的子网&#xff0c;超网可以减少路由入侵的数量&#xff0c;从而提高网络的效率。 超网的实现基于合并多个具有连续IP地址…

html 首行缩进2字符

1. html 首行缩进2字符 1.1. 场景 在Html开发中让一段文字&#xff08;富文本等&#xff09;首行缩进两个文字&#xff0c;可能在前面加上8个“ ”&#xff0c;因为过去对CSS不熟悉&#xff0c;这种方法实现虽然比较直接&#xff0c;但是文字多的时候会有很多“ ”充斥在代码中…

openGauss 6.0安装过程解除对root用户依赖之gs_preinstall

目录 1.执行前提条件 1.1设置OS参数&#xff1a; 1.2定时任务权限 1.3 修改最大文件描述符 2.切换至omm用户&#xff0c;执行preinstall 3.source环境变量 4.执行gs_install 在给客户部署业务系统时&#xff0c;由于openGauss数据库的预安装过程需要用到root用户执行&am…

SD3+ComfyUI文生图生成指南

随着人工智能技术的飞速发展&#xff0c;文生图技术已经越来越成熟。SD3&#xff08;Stable Diffusion 3 Medium&#xff09;模型以其20亿参数的庞大容量&#xff0c;提供了高质量的图像生成能力。结合ComfyUI这一灵活的节点式操作界面&#xff0c;用户可以更加高效地进行创作。…

企业电脑防泄密用什么加密软件?10款2024年企业文件加密软件推荐

在当今信息化时代&#xff0c;企业数据安全已成为重中之重。文件加密软件能够有效保护敏感信息&#xff0c;防止数据泄露和未经授权的访问。本文将为您推荐十款优秀的企业文件加密软件&#xff0c;帮助企业提高信息安全性。 1.安秉网盾加密软件 安秉网盾加密软件是一款新一代…

虚拟机Linux的坑 | VMware无法从主机向虚拟机 跨系统复制粘贴拖动 文件/文本

这个情况下&#xff0c;还是没办法跨系统拖拽文件 解决办法&#xff1a; 在终端中输入命令 sudo apt-get autoremove open-vm-tools sudo apt-get install open-vm-tools sudo apt-get install open-vm-tools-desktop过程中只要需要选择是否覆盖的地方&#xff0c;都输入&…

8款StableDiffusion插件助你一臂之力

前言 在AI绘画领域&#xff0c;Stable Diffusion&#xff08;SD&#xff09;绝对是设计师和艺术家们最爱用的工具之一。它给设计师们带来了无限的创作灵感&#xff0c;不管是数字艺术、概念设计还是角色建模&#xff0c;都能让设计师们受益匪浅&#xff0c;大大提高他们的出图…

设计开发一个data-table

前言 在日常开发中&#xff0c;数据表格扮演着至关重要的角色。它以结构化的形式展现信息&#xff0c;使数据清晰易懂&#xff0c;开发者基于此类表格可以对其进行拓展和复用&#xff0c;本篇文章我们将循序渐进地介绍如何构建一个功能完善、易于使用的表格组件&#xff0c;并…

Coze插件发布!PDF转Markdown功能便捷集成,打造你的专属智能体

近日&#xff0c;TextIn开发的PDF转Markdown插件正式上架Coze。 在扣子搜索“pdf转markdown”&#xff0c;或在Coze搜索“pdf2markdown” 即可找到插件&#xff0c;在你的专属智能体中便捷使用文档解析功能。 如果想测试解析插件在你需要的场景下表现如何&#xff0c;可以直接…

数据链路层 I(组帧、差错控制)【★★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 为了把主要精力放在点对点信道的数据链路层协议上&#xff0c;可以采用下图&#xff08;a&#xff09;所示的三层模型。在这种三层模型中&#xff0c;不管在哪一段…

09.直线图

9. 直线图 9.1 普通直线图 self.add_heading("直线图", level1)self.add_heading("普通直线图", level2)# 数据源data [10, 20]data2 [40, 60]data3 [80,90]self.add_quick_chart(data[[2018,2024],data, data2, data3],series[pool1使用情况(TiB),poo…

大数据学习-Spark基础入门

一、Spark是什么&#xff1f; Stack Overflow的数据可以看出&#xff0c;2015年开始Spark每月的问题提交数量已经超越Hadoop&#xff0c;而2018年Spark Python版本的API PySpark每月的问题提交数量也已超过Hadoop。2019年排名Spark第一&#xff0c;PySpark第二&#xff1b;而十…

【三维目标检测模型】ImVoxelNet

【版权声明】本文为博主原创文章&#xff0c;未经博主允许严禁转载&#xff0c;我们会定期进行侵权检索。 参考书籍&#xff1a;《人工智能点云处理及深度学习算法》 ImVoxelNet是一种基于RGB图像的三维目标检测模型&#xff0c;发表在WACV 2022 《ImVoxelNet: Image to Vo…

记事本/软件商店/xbox打不开(不会丢失数据)(保姆级教程)

软件商店的安装 &#xff1a; 在某些情况下&#xff0c;系统更新可能导致本地账户和微软账户出现问题&#xff0c; 使得更新似乎只影响到了一个账户&#xff0c;而非我当前使用的账户。 这会导致我环境中的某些Windows自带应用&#xff0c;如微软商店、电影与电视、画图、记事…

鸿蒙开发入门day10-组件导航

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;还请三连支持一波哇ヾ(&#xff20;^∇^&#xff20;)ノ&#xff09; 目录 组件导航 (Navigation) 设置页面显示模式 设置标题栏模式 设置菜…