数据结构:链表经典算法OJ题
目录
前言
一、移除链表元素
二、反转链表
三、合并两个有序链表
四、链表的中间节点
五、环形链表的约瑟夫问题
前言
在了解了链表的相关知识后,我们还需要一些题目进行练习加深对链表这方面知识的理解,也可以用来检测链表这块学的的怎么样,废话不多说,开始上手。
一、移除链表元素
这里给上题目链接感兴趣的可以看一下(移除链表元素),
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点 。
看题目描述,我们需要删除链表中链表节点为特定值的节点。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode*a=NULL;struct ListNode*b=NULL;if(head==NULL)return head;while(head){if(head->val!=val){if(a==NULL)a=b=head;else{b->next=head;b=b->next;}}head=head->next;}if(b)b->next=NULL;return a;
}
首先,如果链表本身为空,就可以直接返回一个空指针,如果不为空就可以开始下一个阶段,先创建两个指针a,b指向开始给的头结点,让初始头结点开始遍历,如果遇到节点值为特定值就让b节点指向初始头结点的下一个,相当于跳过了这个节点,最后遍历完,如果b节点不为空,就将b的下一个节点置空,相当于是把那些带有特定值的节点删除了。
二、反转链表
这里先给上题目链接(反转链表)
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
这里先给上代码,慢慢来讲解一下。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* reverseList(struct ListNode* head) {if(head==NULL)return head;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;
}
首先还是要判断链表是否为空,空链表直接返回就行了,这里需要创建三个指针,在遍历链表时,将当前节点的 next 指针改为指向前一个节点,由于节点没有引用其前一个节点,因此必须事先存储其前一个节点,在更改引用之前,还需要存储后一个节点,最后返回新的头引用。
三、合并两个有序链表
题目链接(合并有序链表)
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
这道题让我们把两个有序链表合并在一起并且合并后的链表依然有序,这里先上代码,后面讲解。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {if(list1==NULL)return list2;if(list2==NULL)return list1;struct ListNode*n1=(struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode*n2=n1;while(list1&&list2){if(list1->val<=list2->val){n2->next=list1;list1=list1->next;n2=n2->next;}else{n2->next=list2;list2=list2->next;n2=n2->next;}}if(list1)n2->next=list1;if(list2)n2->next=list2;struct ListNode*c=n1->next;free(n1);n1=NULL;return c;
}
首先判断两个有序链表中是否有空链表,如果有一方为空链表,就可以直接返回另一个链表了,需要开辟一个新的链表,将两个链表的每一个值一一比较排个序,再一个一个的放入新的链表当中。
四、链表的中间节点
题目链接(链表的中间节点)
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
这道题可以用很多种方式写出来,这里用的是快慢指针的方式,还有计数器法等方式(计数器法就是先遍历一遍链表算出有多少个节点,再除以二,按照除后的数字在遍历一遍到中间节点位子),这里快慢指针法就先上代码,后面讲解。
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {struct ListNode*a=head;int i=0;while(head){head=head->next;i++;}int count=i/2;while(count>0){a=a->next;count--;}return a;
}
让俩个指针开始时同时指向头结点,一个一次走一步,一个每次走两步,在快指针到达尾节点或者空节点时(奇数节点链表和偶数节点链表会不一样),慢指针就会在中间节点的位置(奇数节点指针会在中间节点,偶数节点指针会在中间两个节点的后一个节点),最后输出慢指针就行了。
五、环形链表的约瑟夫问题
题目链接(约瑟夫问题)
描述
编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。
下一个人继续从 1 开始报数。
n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?
示例
输入:
5,2
返回值:
3
说明:
开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开
1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开
1,3,5,从5开始报数,5->1,1->2编号为1的人离开
3,5,从3开始报数,3->1,5->2编号为5的人离开
最后留下人的编号是3
先上代码,后面慢慢讲解。
#include<stdlib.h>#include<stdio.h>
typedef struct music
{int data;struct music* next;
}music;
music*initial(int n)
{music*a=(music*)malloc(sizeof(music));a->data=n;a->next=NULL;return a;
}
music*creat(int n)
{music*a=initial(1);music*b=a;for(int i=2;i<=n;i++){b->next=initial(i);b=b->next;}b->next=a;return b;
}
int ysf(int n, int m ) {music*a=creat(n);music*head=a->next;int count=1;while(head->next!=head){if(count==m){a->next=head->next;free(head);head=a->next;count=1;}else{a=head;head=head->next;count++;}}return head->data;
}
这道题涉及到了链表的创建,所以就需要一个包含数据成员的结构体以及初始化函数和创建链表相关函数,在实现约瑟夫问题的函数中,先创建head和a指针,head指针就是扮演着正在报数的那个人,a这是head的前一个节点,当报数的head报道特定的数字,a就会跳过这个节点,然后再把这个节点释放掉,head继续在a->next,循环着操作,留下最后一个就可以输出结果了。
本篇内容就到这里了,没到题目都给了链接,可以自己去尝试解题,光听的话效果没那么好。
相关文章:

数据结构:链表经典算法OJ题
目录 前言 一、移除链表元素 二、反转链表 三、合并两个有序链表 四、链表的中间节点 五、环形链表的约瑟夫问题 前言 在了解了链表的相关知识后,我们还需要一些题目进行练习加深对链表这方面知识的理解,也可以用来检测链表这块学的的怎么样&#…...
【线性代数】【二】2.2 极大线性无关组与向量空间的基
文章目录 前言一、极大线性无关组二、向量空间的基三、向量维数与向量空间维数总结 前言 上一篇中我们介绍了向量空间的概念,并且学习了对任意给出的一组向量,如果构造一个向量空间。本文将更加细致的去分析张成一个向量空间,具有哪些性质。…...
OD C卷 - CPU算力分配
CPU算力分配 两组服务器A、B, 每组有多个算力不同的CPU;为了让两组服务器的算力和相等,允许两组各选出一个CPU进行一次交换;求两组中用于交换的CPU算力,从A中选出的算力尽可能小; 输入描述: 第一行 输入L…...
matlab实现红绿灯识别
在MATLAB中实现红绿灯识别通常涉及图像处理技术,包括颜色分割、形态学操作、边缘检测等步骤。下面我将给出一个基本的框架和示例代码,用于在MATLAB中识别图像中的红绿灯。 步骤 1: 读取图像 首先,你需要有一张包含红绿灯的图像。 img imr…...
base64 转 pdf
工作中经常会遇到一些签名的pdf传输,一般都是base64编码,这样就需要我们手动转为pdf, 其实根本不需要自己使用pdf的库写入,只是数据的简单写入就行 package mainimport ("encoding/base64""fmt""os&quo…...
vue2项目微信小程序的tabs切换效果
在 Vue 2 项目中实现类似微信小程序的 tabs 切换效果,可以通过 Vue 的 router-view 和 <router-link> 来完成。这里我们使用 Vue Router 来创建一个标签页切换的效果。 步骤 1: 安装 Vue Router 如果还没有安装 Vue Router,首先需要安装它&#…...
WPF动画的使用
前言 弹幕是什么?这里是使用动画将控件弹起来,通过C#提供的多样化动画类型,我们可以制做出丰富的界面效果。主要有基于时间的动画和基于属性的动画。 1、Animatable 一个提供动画支持的抽象类。 继承 Object DispatcherObject Depende…...

跑腿代购app系统源码开发及功能分析
随着互联网技术的飞速发展和人们生活节奏的加快,跑腿代购服务作为一种便捷的生活方式,正逐渐渗透到我们日常生活的方方面面。从日常购物、餐饮外卖到文件传递、药品代购,跑腿服务以其高效、灵活的特点赢得了广大用户的青睐。而支撑这一服务高…...
mysql数据库:字符串函数
mysql数据库:字符串函数 mysql数据库:字符串函数 concat(str1,str2,…strn) 连接str1,str2,…,strn为一个字符串 select concat(abc,def)replace(str,a,b) 用字符串b替换str中所有出现的字符串a insert(str,x,y,instr…...

C语言实现游戏2048(超详细!!!超易懂!!!)
2048是众所周知的一款经典游戏,在曾经没有智能电脑和手机的年代,也陪伴了我们许多年。那今天就让我们用C语言来回顾一下这款游戏吧~ 一、游戏2048的思路 2048游戏的玩法是在初始的时候,给玩家一个4*4格子的,其中内容全为空的棋盘…...

MATLAB代码检查工具PolySpace
概述 PolySpace是MATLAB里面代码静态检查工具。通过检查源代码,可以确定可能在哪里发生潜在的运行时错误,例如算术溢出,缓冲区溢出等等。它最大的特点是可以检查车企常用的MISRA C标准,还免费,就让各大车企爱不释手。…...
FPGA设计之跨时钟域(CDC)设计篇(5)----同步FIFO的两种设计方法(计数器法/高位扩展法 | 手撕代码)
1、什么是FIFO? FIFO(First In First Out) 是一种先进先出的数据缓存器,在逻辑设计里面用的非常多。它是一种存储器结构,被广泛应用于芯片设计中。FIFO由存储单元队列或阵列构成,第一个被写入队列的数据也是第一个从队列中读出的数据。 FIFO 设计可以说是逻辑设计人员必须…...

快速掌握Vue:基础命令详解
1. Vue概述 Vue.js(读音 /vjuː/, 类似于 「view」) 是一套构建用户界面的 「渐进式框架」。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库…...
MySQL——索引(二)创建索引(1)创建表的时候创建索引
要想使用索引提高数据表的访问速度,首先要创建一个常引。创建索引的方式有三种,具体如下。 创建表的时候可以直接创建索引,这种方式最简单、方便,其基本的语法格式如下所示: CREATE TABLE 表名 (字段名 数据类型 [完整性约束条件…...

源代码加密怎么做?企业常用十款源代码加密软件排行榜
在数字化信息时代,源代码是企业的核心资产之一。保护源代码的安全不仅能防止知识产权泄露,还能保护企业的竞争优势。因此,源代码加密成为企业信息安全的重要环节。 源代码是软件的基础,包含了企业独特的技术和解决方案。未加密的源…...

python 文件打开、读、关闭练习
一、题目要求 二、代码实现 f open("D:\\workspace\\word.txt" , "r", encoding "UTF-8")# 方案一 # content f.read() # count content.count("itheima") # print(f"itmeiha在文件中出现了:{count}次")# 方案…...
迈向大规模小目标检测:综述与数据集
为了准确检测小目标,领域内现有方法大多基于通用目标检测范式进行针对性改进,根据这些改进所采用关键技术的不同,可以分为六种类别:(1)面向样本的方法;(2)基于尺度感知的…...

69、zabbix自动、代理、snmp监控
一、zabbix 1.1、自动发现 [roottest1 ~]# systemctl stop firewalld [roottest1 ~]# setenforce 0 [roottest3 ~]# vim /etc/hosts 192.168.168.21 test1 192.168.168.23 test3 [roottest1 ~]# vim /etc/hosts 192.168.168.21 test1 192.168.168.23 test3 ------------…...
搜索引擎设计:如何避免大海捞针般的信息搜索
搜索引擎设计:如何避免大海捞针般的信息搜索 随着互联网的发展,信息的数量呈爆炸式增长。如何在海量信息中快速、准确地找到所需信息,成为了搜索引擎设计中的核心问题。本文将详细探讨搜索引擎的设计原理和技术,从信息获取、索引…...

设计模式- 数据源架构模式
表数据入口(Table Data Gateway) 充当数据库表访问入口的对象。一个实例处理表中所有的行。 表数据入口包含了用于访问单个表或者视图的所有SQL,如选择、插入、更新、删除等。其他代码调用它的方法来实现所有与数据库的交互。 运行机制 表数据入口包括的每个方法…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...