初阶数据结构:链表相关题目练习(补充)
目录
- 1. 单链表相关练习题
- 1.1 移除链表元素
- 1.2 反转链表
- 1.3 链表的中间结点
- 1.4 链表的倒数第k个结点
- 1.5 合并两个有序链表
- 1.6 链表分割
- 1.7 链表的回文结构
- 1.8 相交链表
- 1.9 判断一个链表中是否有环
- 1.10 寻找环状链表相遇点
- 1.11 链表的深度拷贝
1. 单链表相关练习题
注:单链表结构上存在一定缺陷,所以链表相关的题目一般都针对与单链表。
1.1 移除链表元素
题目要求:
题目信息:
- 头节点head
- 移除值val
题目链接:
移除链表元素
方法(顺序处理法):
思路:分析链表结构与结点所处的位置(是否为空链表,结点是否为头结点),分情况依次处理。
过程演示:

struct ListNode* removeElements4(struct ListNode* head, int val)
{struct ListNode* pre = NULL;struct ListNode* cur = head;while (cur){if (cur->val == val){//头删if (cur == head){head = head->next;free(cur);cur = head;}else//中间删{pre->next = cur->next;free(cur);cur = pre->next;}}else{pre = cur;cur = cur->next;}}return head;
}
1.2 反转链表
题目要求:
题目链接:
反转链表
过程演示:
struct ListNode* reverseList(struct ListNode* head)
{struct ListNode* pre = NULL;struct ListNode* mid = head;struct ListNode* cur = NULL;if(head){cur = head->next;}while(mid){mid->next = pre;pre = mid;mid = cur;if(cur){cur = cur->next;}}return pre;}
1.3 链表的中间结点
题目要求:
题目链接:
链表的中间结点
过程演示(快慢指针法):
struct ListNode* middleNode(struct ListNode* head)
{struct ListNode* fast = head;struct ListNode* slow = head;while(fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;}return slow;
}
1.4 链表的倒数第k个结点
题目要求:
题目链接:
倒数第k个结点
过程演示:
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k )
{struct ListNode* cur = pListHead;struct ListNode* pre = pListHead;while(cur && k--){cur = cur->next;}if(k > 0){pre = NULL;}while(cur){pre = pre->next;cur = cur->next;}return pre;
}
1.5 合并两个有序链表
题目要求:
题目链接:
合并两个链表
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{struct ListNode* newhead = NULL;struct ListNode* cur = NULL;struct ListNode* newnode = NULL;if(list1 == NULL)return list2;if(list2 == NULL)return list1;while(list1 != NULL && list2 != NULL){if(list1->val <= list2->val){newnode = list1;list1 = list1->next;}else{newnode = list2;list2 = list2->next;}if(newhead == NULL){newhead = newnode;newnode->next = NULL;cur = newhead;}else{//在遍历过程中,list1 或 list2 会等于 NULLcur->next = newnode;if(newnode != NULL){newnode->next = NULL;cur = cur->next;}}}//有一个链表本就为空if(list1){cur->next = list1;}if(list2){cur->next = list2;}return newhead;
}
1.6 链表分割
题目要求:
题目链接:
合并两个链表
ListNode* BuyNewNode(int val){ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));newnode->val = val;newnode->next = nullptr;return newnode;}ListNode* partition(ListNode* pHead, int x) {ListNode* newhead1 = nullptr;ListNode* end1 = nullptr;ListNode* newhead2 = nullptr;ListNode* end2 = nullptr;ListNode* cur = pHead;while(cur){if(cur->val < x){if(newhead1 == nullptr){newhead1 = BuyNewNode(cur->val);end1 = newhead1; }else {end1->next = BuyNewNode(cur->val);end1 = end1->next;}}else {if(newhead2 == nullptr){newhead2 = BuyNewNode(cur->val);end2 = newhead2; }else {end2->next = BuyNewNode(cur->val);end2 = end2->next;}}cur = cur->next;}if(newhead1 == nullptr){newhead1 = newhead2;}else {end1->next = newhead2;}return newhead1;}
1.7 链表的回文结构
题目要求:
题目链接:
回文串
ListNode* reverse(ListNode* head){ListNode* pre = nullptr;ListNode* mid = head;ListNode* cur = head->next;while (mid){mid->next = pre;pre = mid;mid = cur;if (cur){cur = cur->next;}}return pre;}bool chkPalindrome(ListNode* A){//找相同,逆置//逐点比较//回文结构存在奇数个结点//获取中间结点ListNode* fast = A;ListNode* slow = A;while(fast && fast->next){fast = fast->next->next;if(fast){slow = slow->next;}}//表1ListNode* newhead2 = slow->next;//表2slow->next = nullptr;ListNode* newhead1 = reverse(A);if(fast){newhead1 = newhead1->next;}while (newhead1 && newhead2 && newhead1->val == newhead2->val){newhead1 = newhead1->next;newhead2 = newhead2->next;}if (newhead1 == nullptr && newhead2 == nullptr){return true;}return false;}
1.8 相交链表
题目要求:
题目链接:
相交链表
void swap(struct ListNode** node1, struct ListNode** node2)
{struct ListNode* tmp = *node1;*node1 = *node2;*node2 = tmp;
}struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{struct ListNode* short_list1 = headA;struct ListNode* short_list2 = headA;struct ListNode* long_list1 = headB;struct ListNode* long_list2 = headB;while(short_list1 && long_list1){short_list1 = short_list1->next;long_list1 = long_list1->next;}if(short_list1){swap(&short_list1, &long_list1);swap(&short_list2, &long_list2);}while(long_list1){long_list1 = long_list1->next;long_list2 = long_list2->next;}//while((short_list2 && long_list2) || short_list2 != long_list2)while(short_list2 && long_list2 && short_list2 != long_list2){long_list2 = long_list2->next;short_list2 = short_list2->next;}return short_list2;
}
1.9 判断一个链表中是否有环
题目要求:
题目链接:
判断是否有环
//逻辑步骤存疑
bool hasCycle(struct ListNode *head)
{struct ListNode* fast = head;struct ListNode* slow = head;//err: while(fast && slow != fast)while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast){return true;}}return false;
}
1.10 寻找环状链表相遇点
题目要求:
题目链接:
寻找环状链表相遇点
思路依靠结论:一个结点从起始点,一个结点从相遇点(快慢指针相遇点),以同速行走(一次走一步),当他们再一次初次相遇时,此相遇结点即为入环点。
struct ListNode *detectCycle(struct ListNode *head)
{//快慢指针确定首次相遇点//起始点与相遇点出发,同速移动,最后的相遇的点即为环的进入点struct ListNode* fast = head;struct ListNode* slow = head;//遍历寻找相遇点while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow){break;}}//判断是否为环状链表if(fast == NULL || fast->next == NULL){return NULL;}slow = head;while(fast != slow){fast = fast->next;slow = slow->next;}return fast;
}
1.11 链表的深度拷贝
题目要求:
>题目链接:
链表的深度拷贝
//思路:
//生成拷贝结点
//调整拷贝结点的指针
//还原原链表,链接拷贝结点
struct Node* BuyNewNode(int val)
{struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));newnode->val = val;newnode->next = NULL;newnode->random = NULL;return newnode;
}struct Node* copyRandomList(struct Node* head)
{struct Node* node1 = head;//判断是否为空链表if(head == NULL){return head;}//创建新节点while (node1){struct Node* newnode = BuyNewNode(node1->val);newnode->next = node1->next;node1->next = newnode;node1 = node1->next->next;}//调整新节点的随机指针struct Node* node2 = head->next;node1 = head;while (node2){if (node1->random){node2->random = node1->random->next;}node1 = node1->next->next;if (node2->next){node2 = node2->next->next;}else{node2 = node2->next;}}//还原链表,链接新链表node1 = head;node2 = head->next;struct Node* newhead = head->next;while (node1){node1->next = node1->next->next;if (node2->next){node2->next = node2->next->next;}node1 = node1->next;node2 = node2->next;}return newhead;
}
相关文章:
初阶数据结构:链表相关题目练习(补充)
目录 1. 单链表相关练习题1.1 移除链表元素1.2 反转链表1.3 链表的中间结点1.4 链表的倒数第k个结点1.5 合并两个有序链表1.6 链表分割1.7 链表的回文结构1.8 相交链表1.9 判断一个链表中是否有环1.10 寻找环状链表相遇点1.11 链表的深度拷贝 1. 单链表相关练习题 注࿱…...
java: 错误: 不支持发行版本 5
目录 一、问题描述 二、解决办法 方法一:修改idea设置中的jdk版本 方法二:配置pom.xml文件 方法三:配置maven的xml文件(推荐) 三、结果 一、问题描述 问题描述:今天创建了一个maven项目,…...
springSecruity--->和springboot结合的跨域问题
🤦♂️这个是我在springboot中使用springSecruity写一个小demo时遇到的问题,记录下来🤦♂️ 文章目录 跨域请求springboot项目中使用springSecruity导致跨域请求CrossOrigin请求失效解决方法springboot 中的跨域方法 跨域请求 什么是跨…...
网关kong记录接口处理请求和响应插件 tcp-log-with-body的安装
tcp-log-with-body 介绍 Kong的tcp-log-with-body插件是一个高效的工具,它能够转发Kong处理的请求和响应。这个插件非常适用于需要详细记录API请求和响应信息的情景,尤其是在调试和排查问题时。 软件环境说明 kong version 2.1.4 - 2.8.3 [可用亲测]C…...
ElasticSearch之Completion Suggester
写在前面 通过completion suggester可以实现如下的效果: 其实就是做的like xxx%这种。通过FST这种数据结构来存储,实现快速的前缀匹配,并且可以将es所有的数据加载到内存中所以速度completion的查询速度非常快。 需要注意,如果…...
ant 布局组件 组件等高设置
背景: 想实现一个和content等高的侧边栏,并增加侧边栏导航。 ant组件概述 Layout:布局容器,其下可嵌套 Header Sider Content Footer 或 Layout 本身,可以放在任何父容器中。Header:顶部布局,…...
不可多得的干货,网易的朋友给我这份339页的Android面经
这里先放上目录 一 性能优化 1.如何对 Android 应用进行性能分析 android 性能主要之响应速度 和UI刷新速度。 首先从函数的耗时来说,有一个工具TraceView 这是androidsdk自带的工作,用于测量函数耗时的。 UI布局的分析,可以有2块&#x…...
Qt项目:网络1
文章目录 项目:网路项目1:主机信息查询1.1 QHostInfo类和QNetworkInterface类1.2 主机信息查询项目实现 项目2:基于HTTP的网络应用程序2.1 项目中用到的函数详解2.2 主要源码 项目:网路 项目1:主机信息查询 使用QHostI…...
软件测试有哪些常用的测试方法?
软件测试是软件开发过程中重要组成部分,是用来确认一个程序的质量或者性能是否符合开发之前提出的一些要求。软件测试的目的有两方面,一方面是确认软件的质量,另一方面是提供信息,例如,给开发人员或者程序经理反馈意见…...
【C语言基础】:深入理解指针(一)
文章目录 一、内存和地址1. 内存2. 如何理解编址 二、指针变量和地址2.1 取地址操作符(&)2.2 指针变量和解引用操作符(*)2.2.1 指针变量2.2.2 如何拆解指针变量2.2.3 解引用操作符 2.3 指针变量的大小 三、指针变量类型的意义3.1 指针的解引用3.2 指针 - 整数3.3 void*指针…...
单点故障解决方案之Smart Link与Monitor Link
-SmartLink技术,创建Smart Link 组。在该组中,加入两个端口。其中1个端口是主端口,也称之为Master端口。另外1个端口是备份端口:也称之为 Slave 端口。 -Monitor Link 组也称之为“监控链路组,由上行端口和下行端口共同组成。下行…...
QT之QSharedMemory共享内存
QSharedMemory是qt提供对共享内存操作的类,主要用来对内存卡写数据和读数据。 常用api: 1、void QSharedMemory::setKey(const QString &key) 为共享内存设置键值。如何当前的内存共享对象已经链接到底层的共享内存段(isAttached)&…...
string 类 经典习题之数字字符相加
题目: 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。 题目来源࿱…...
通讯录——C语言实现
头文件Contact.h #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #pragma once #define MAX 100 #define MAX_NAME 20 #define MAX_SEX 5 #define MAX_TELE 12 #define MAX_ADDR 30//表示一个人的信息 //struct…...
优思学院|3步骤计算出Cpk|学习Minitab
在生产和质量管理中,准确了解和控制产品特性至关重要。一个关键的工具是Cpk值,它是衡量生产过程能力的重要指标。假设我们有一个产品特性的规格是5.080.02,通过收集和分析过程数据,我们可以计算出Cpk值,进而了解生产过…...
【Java编程进阶之路 06】深入探索:JDK、JRE与JVM的关系与差异
JDK、JRE与JVM:揭开Java运行环境的神秘面纱 在Java开发者的日常工作中,JDK、JRE和JVM这三个概念是不可或缺的。它们构成了Java应用程序的运行环境,但很多初学者可能对这三者的关系和差异感到困惑。本文旨在详细解析JDK、JRE和JVM之间的关系&…...
Linux中的touch命令
在Linux中,touch命令主要用于创建空的文件或者更新已存在文件的时间戳。下面是 touch命令的使用方式和示例说明: 创建空文件 要创建一个空文件,可以使用 touch命令并指定文件名,如下所示: touch new_fi…...
智能驾驶规划控制理论学习-基于采样的规划方法
目录 一、基于采样的规划方法概述 二、概率路图(PRM) 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树(RRT) 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…...
二叉树——二叉树所有路径
二叉树所有路径 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [1,2,3,null,5] 输出:["1->2->5","1-…...
算法训练营day38(补),动态规划6
package main func max(a, b int) int { if a > b { return a } return b } 背包最大重量为4。 物品为: 重量价值物品0115物品1320物品2430 每件商品都有无限个! 问背包能背的物品最大价值是多少? func package03(weight, value []…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...








题目链接:
