leetcode707----设计链表【链表增删改打印等操作】
目录
一、题目介绍
二、单链表
2.1 创建链表类
2.1.1 定义链表节点结构体代码块
2.1.2 MyLinkedList类的构造函数
2.1.3 私有成员变量
2.2 接口1:获取第下标为index的节点的值
2.3 接口2:头部插入节点
2.4 接口3:尾部插入节点
2.5 接口4:在下标为index的节点前插入新节点
2.6 接口5:删除下标为index的节点
2.7 打印链表
2.8 主函数部分
2.9 总体代码
一、题目介绍
题目链接:707. 设计链表 - 力扣(LeetCode)
题目简介
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
MyLinkedList()初始化MyLinkedList对象。int get(int index)获取链表中下标为index的节点的值。如果下标无效,则返回-1。void addAtHead(int val)将一个值为val的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。void addAtTail(int val)将一个值为val的节点追加到链表中作为链表的最后一个元素。void addAtIndex(int index, int val)将一个值为val的节点插入到链表中下标为index的节点之前。如果index等于链表的长度,那么该节点会被追加到链表的末尾。如果index比长度更大,该节点将 不会插入 到链表中。void deleteAtIndex(int index)如果下标有效,则删除链表中下标为index的节点。
题目分析:
这道题目设计链表的五个接口:
- 获取链表第index个节点的数值
- 在链表的最前面插入一个节点
- 在链表的最后面插入一个节点
- 在链表第index个节点前面插入一个节点
- 删除链表的第index个节点
可以说这五个接口,已经覆盖了链表的常见操作,是练习链表操作非常好的一道题目
链表操作的两种方式:
- 直接使用原来的链表来进行操作。
- 设置一个虚拟头结点在进行操作。
下面采用的设置一个虚拟头结点(这样更方便一些,大家看代码就会感受出来)。
二、单链表
2.1 创建链表类
类的成员(包括嵌套结构体)默认是私有的,除非你显式指定它们为公有的(public)。
#include<iostream>
class MyLinkedList{public:// 定义链表节点结构体struct LinkedNode{int val; // 单链表的数据域LinkedNode* next; // 单链表的指针域LinkedNode(int x):val(x),next(nullptr){} // 节点的构造函数};// 初始化链表,MyLinkedList的构造函数MyLinkedList(){virtualHead = new LinkedNode(0); // 定义虚拟头节点ListSize = 0; // 链表的初始长度置为 0 }private:LinkedNode* virtualHead; // 链表的虚拟节点int ListSize; // 链表的长度};
2.1.1 定义链表节点结构体代码块
// 定义链表节点结构体struct LinkedNode{int val; // 单链表的数据域LinkedNode* next; // 单链表的指针域LinkedNode(int x):val(x),next(nullptr){} // 节点的构造函数};
-
LinkedNode是链表的节点结构体。每个节点包含两个成员:val:存储节点的数据,类型为int。next:指向下一个节点的指针。若该节点为链表的最后一个节点,则next为nullptr。
-
构造函数
LinkedNode(int x)用于初始化节点的值,并将next指针初始化为nullptr,表示该节点暂时没有指向任何其他节点。
2.1.2 MyLinkedList类的构造函数
MyLinkedList() {virtualHead = new LinkedNode(0); // 定义虚拟头节点ListSize = 0; // 链表的初始长度置为 0
}
MyLinkedList是MyLinkedList类的构造函数,用于初始化链表。virtualHead = new LinkedNode(0):这里创建了一个 虚拟头节点,它的值为0,并且next指向nullptr。虚拟头节点通常用于简化链表的操作,避免在处理链表时需要单独处理头节点(例如插入、删除操作时)。ListSize = 0:初始化链表的长度为0,因为此时链表是空的。
2.1.3 私有成员变量
private:LinkedNode* virtualHead; // 链表的虚拟节点int ListSize; // 链表的长度
virtualHead:指向链表虚拟头节点的指针。虚拟头节点本身不存储有效数据,它的存在是为了简化链表操作,尤其是在进行头节点的插入和删除时。ListSize:一个整数,表示链表的当前大小。每当进行节点的插入或删除时,ListSize会相应更新。
2.2 接口1:获取第下标为index的节点的值
//int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。// 注意index是从0开始的,第0个节点就是头结点,即链表中第一个节点int get(int index){// 判断链表是否为空if(virtualHead->next == nullptr){return -1;}else{ // 链表非空// 首先判断下标的有效性if(index >(ListSize - 1) || index < 0){return -1;}// 下标有效,开始寻找下标为index的节点的值LinkedNode* ptr = virtualHead->next; // 定义遍历链表的指针while(index){ // 假设要遍历下标为0的节点,即链表的第1个节点,链表的头节点,index=0不符合while条件,直接返回ptr->valptr=ptr->next;index--;}return ptr->val;} }
这段代码实现了一个 get 函数,用于获取链表中指定下标 index 的节点值。它首先检查链表是否为空若为空,直接返回-1,若不为空,再检查下标的有效性,然后遍历链表找到对应下标的节点,并返回该节点的值。
可能的优化与改进:
-
性能考虑:
- 目前的实现是线性时间复杂度
O(n),因为需要遍历链表中的index+1【index表示的是下标索引,从0开始的】个节点。如果链表很长,查找某个节点的值会比较慢。 - 对于更高效的实现,可以考虑维护一个指向链表尾部的指针,这样在获取末尾节点时可以更快地实现从两端往中间遍历。【双向链表实现】
- 目前的实现是线性时间复杂度
2.3 接口2:头部插入节点
// void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。void addAtHead(int val){LinkedNode* NewHead= new LinkedNode(val); // 定义头插节点LinkedNode* OldHead = virtualHead->next; virtualHead->next = NewHead;// 虚拟头节点的指针域存放新的头节点的地址NewHead->next=OldHead;// 新头节点的指针域存放旧的头节点的地址ListSize++;// 添加一个新的头节点之后,链表的长度+1}
2.4 接口3:尾部插入节点
// void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。void addAtTail(int val){LinkedNode* NewNode = new LinkedNode(val);LinkedNode* ptr = virtualHead->next; // 定义一个遍历链表的指针while(ptr->next!=nullptr){ // ptr->next!=nullptr说明当前节点的下一个节点是存在的,如果ptr->next=nullptr,说明当前节点的下一个节点不存在,此时遍历到链表的尾端ptr = ptr->next;}ptr->next=NewNode;ListSize++;}
2.5 接口4:在下标为index的节点前插入新节点
//void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。//如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。void addAtIndex(int index, int val){// 判断index的有效性if(index<0|| index>ListSize){ //下标越界std::cout<<"下标 index 越界!" <<std::endl;}if(index==ListSize){ // 若插入的下标值等于链表的原长度,那采用链表的尾插法进行插入addAtTail(val); // 直接调用尾插法函数}if(index==0){ // 若插入的下标值等于0,那采用链表的头插法进行插入addAtHead(val); // 直接调用头插法函数}LinkedNode* IndexNode = new LinkedNode(val); // 创建要插入的节点LinkedNode* ptr = virtualHead; // 定义遍历指针while(index){ // 找到下标为index的位置ptr = ptr->next; // 遍历指针依次后移index--;}IndexNode->next = ptr->next;ptr->next = IndexNode;ListSize++;}
2.6 接口5:删除下标为index的节点
// 链表的节点删除操作// void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。void deleteAtIndex(int index){// 判断下标的合理性if(index<0||index>ListSize-1){std::cout<<"下标 index 越界!"<<std::endl;}else{LinkedNode* Ptr = virtualHead; // 遍历指针while(index){ // 找出下标为 index 的节点Ptr=Ptr->next; index--;}Ptr->next = Ptr->next->next; // 删除操作LinkedNode* DeletePtr = Ptr->next; // Deleteptr指向待删除的节点delete DeletePtr;//delete命令只是释放了DeletePtr指针原本所指的那部分内存,//被delete后的指针DeletePtr的值(地址)并非就是NULL,而是随机值。也就是被delete后,//如果不再加上一句DeletePtr=nullptr,DeletePtr会成为乱指的野指针//如果之后的程序不小心使用了DeletePtr,会指向难以预想的内存空间DeletePtr=nullptr;ListSize--; // 删除链表一个节点,链表长度-1}}
2.7 打印链表
// 打印链表中所有的元素void PrintList(){LinkedNode* ptr = virtualHead; // 定义遍历指针while(ptr->next!=nullptr){ // std::cout<<ptr->next->val<<" ";ptr = ptr->next;}std::cout<<std::endl;}
2.8 主函数部分
int main(){MyLinkedList List; // 实例化对象// List.addAtHead(1); // 头插法// List.addAtHead(2); // 头插法// List.addAtHead(3); // 头插法// List.addAtTail(4); // 尾插法// List.PrintList(); // 打印链表中的所有元素// List.addAtIndex(2,5); // 在指定的索引位置处插入新元素// List.PrintList(); // 打印链表中的所有元素// List.deleteAtIndex(6); // 删除指定的索引位置的节点// List.PrintList(); // 打印链表中的所有元素int index_get = 2;int get_ = List.get(index_get); // 获取指定索引位置处的元素if(get_){ // 链表为空时,get函数返回-1,-1=True std::cout<<"链表为空!"<<std::endl;}else{std::cout<<"索引位置为:"<<index_get<<"的值为:"<<get_<<std::endl;}
}
2.9 总体代码
#include<iostream>
class MyLinkedList{public:// 定义链表节点结构体struct LinkedNode{int val; // 单链表的数据域LinkedNode* next; // 单链表的指针域LinkedNode(int x):val(x),next(nullptr){} // 节点的构造函数};// 初始化链表,MyLinkedList的构造函数MyLinkedList(){virtualHead = new LinkedNode(0); // 定义虚拟头节点ListSize = 0; // 链表的初始长度置为 0 }//int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。// 注意index是从0开始的,第0个节点就是头结点,即链表中第一个节点int get(int index){// 判断链表是否为空if(virtualHead->next == nullptr){return -1;}else{ // 链表非空// 首先判断下标的有效性if(index >(ListSize - 1) || index < 0){return -1;}// 下标有效,开始寻找下标为index的节点的值LinkedNode* ptr = virtualHead->next; // 定义遍历链表的指针while(index){ // 假设要遍历下标为0的节点,即链表的第1个节点,链表的头节点,index=0不符合while条件,直接返回ptr->valptr=ptr->next;index--;}return ptr->val;} }// void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。void addAtHead(int val){LinkedNode* NewHead= new LinkedNode(val); // 定义头插节点LinkedNode* OldHead = virtualHead->next; virtualHead->next = NewHead;// 虚拟头节点的指针域存放新的头节点的地址NewHead->next=OldHead;// 新头节点的指针域存放旧的头节点的地址ListSize++;// 添加一个新的头节点之后,链表的长度+1}// void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。void addAtTail(int val){LinkedNode* NewNode = new LinkedNode(val);LinkedNode* ptr = virtualHead->next; // 定义一个遍历链表的指针while(ptr->next!=nullptr){ // ptr->next!=nullptr说明当前节点的下一个节点是存在的,如果ptr->next=nullptr,说明当前节点的下一个节点不存在,此时遍历到链表的尾端ptr = ptr->next;}ptr->next=NewNode;ListSize++;}//void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。//如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。void addAtIndex(int index, int val){// 判断index的有效性if(index<0|| index>ListSize){ //下标越界std::cout<<"下标 index 越界!" <<std::endl;}if(index==ListSize){ // 若插入的下标值等于链表的原长度,那采用链表的尾插法进行插入addAtTail(val); // 直接调用尾插法函数}if(index==0){ // 若插入的下标值等于0,那采用链表的头插法进行插入addAtHead(val); // 直接调用头插法函数}LinkedNode* IndexNode = new LinkedNode(val); // 创建要插入的节点LinkedNode* ptr = virtualHead; // 定义遍历指针while(index){ // 找到下标为index的位置ptr = ptr->next; // 遍历指针依次后移index--;}IndexNode->next = ptr->next;ptr->next = IndexNode;ListSize++;}// 链表的节点删除操作// void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。void deleteAtIndex(int index){// 判断下标的合理性if(index<0||index>ListSize-1){std::cout<<"下标 index 越界!"<<std::endl;}else{LinkedNode* Ptr = virtualHead; // 遍历指针while(index){ // 找出下标为 index 的节点Ptr=Ptr->next; index--;}Ptr->next = Ptr->next->next; // 删除操作LinkedNode* DeletePtr = Ptr->next; // Deleteptr指向待删除的节点delete DeletePtr;//delete命令只是释放了DeletePtr指针原本所指的那部分内存,//被delete后的指针DeletePtr的值(地址)并非就是NULL,而是随机值。也就是被delete后,//如果不再加上一句DeletePtr=nullptr,DeletePtr会成为乱指的野指针//如果之后的程序不小心使用了DeletePtr,会指向难以预想的内存空间DeletePtr=nullptr;ListSize--; // 删除链表一个节点,链表长度-1}}// 打印链表中所有的元素void PrintList(){LinkedNode* ptr = virtualHead; // 定义遍历指针while(ptr->next!=nullptr){ // std::cout<<ptr->next->val<<" ";ptr = ptr->next;}std::cout<<std::endl;}private:LinkedNode* virtualHead; // 链表的虚拟节点int ListSize; // 链表的长度};int main(){MyLinkedList List; // 实例化对象// List.addAtHead(1); // 头插法// List.addAtHead(2); // 头插法// List.addAtHead(3); // 头插法// List.addAtTail(4); // 尾插法// List.PrintList(); // 打印链表中的所有元素// List.addAtIndex(2,5); // 在指定的索引位置处插入新元素// List.PrintList(); // 打印链表中的所有元素// List.deleteAtIndex(6); // 删除指定的索引位置的节点// List.PrintList(); // 打印链表中的所有元素int index_get = 2;int get_ = List.get(index_get); // 获取指定索引位置处的元素if(get_){ // 链表为空时,get函数返回-1,-1=True std::cout<<"链表为空!"<<std::endl;}else{std::cout<<"索引位置为:"<<index_get<<"的值为:"<<get_<<std::endl;}
}
推荐观看视频:
帮你把链表操作学个通透!LeetCode:707.设计链表_哔哩哔哩_bilibili
相关文章:
leetcode707----设计链表【链表增删改打印等操作】
目录 一、题目介绍 二、单链表 2.1 创建链表类 2.1.1 定义链表节点结构体代码块 2.1.2 MyLinkedList类的构造函数 2.1.3 私有成员变量 2.2 接口1:获取第下标为index的节点的值 2.3 接口2:头部插入节点 2.4 接口3:尾部插入节点 2.5 接…...
【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝
【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝 问题展示解决办法 问题展示 在使用docker中的consul服务的时候,通过命令行注册相应的服务(比如cloudwego项目的demo_proto以及user服务)失败。 解决办法 经过分析,是…...
【缓存】缓存雪崩与缓存穿透:高并发系统的隐形杀手
缓存雪崩与缓存穿透:高并发系统的隐形杀手 在高并发系统中,缓存是提升性能的重要手段。然而,缓存使用不当也会带来一系列问题,其中最常见的就是缓存雪崩和缓存穿透。这两个问题如果不加以解决,可能会导致系统崩溃&…...
网络协议 HTTP、HTTPS、HTTP/1.1、HTTP/2 对比分析
1. 基本定义 HTTP(HyperText Transfer Protocol) 应用层协议,用于客户端与服务器之间的数据传输(默认端口 80)。 HTTP/1.0:早期版本,每个请求需单独建立 TCP 连接,效率低。HTTP/1.1&…...
DeepSeek实现FunctionCalling调用API查询天气
什么是FunctionCalling Function Calling(函数调用)是大型语言模型(如 OpenAI 的 GPT 系列)提供的一种能力,允许模型在生成文本的过程中调用外部函数或工具,以完成更复杂的任务。通过 Function Calling&am…...
从 Spring Boot 2 升级到 Spring Boot 3 的终极指南
一、升级前的核心准备 1. JDK 版本升级 Spring Boot 3 强制要求 Java 17 及以上版本。若当前项目使用 Java 8 或 11,需按以下步骤操作: 安装 JDK 17:从 Oracle 或 OpenJDK 官网下载,配置环境变量(如 JAVA_HOME&…...
C#设计模式深度解析:经典实现与现代演进 ——基于《设计模式》的.NET技术实践
一、设计模式与C#语言特性融合 C#凭借其面向对象特性、泛型、委托/事件、LINQ等能力,为设计模式提供了更优雅的实现方式。以下通过典型模式展现其技术融合: 1. 工厂方法模式 泛型约束 public interface IProduct<T> where T : new() {void O…...
原子性(Atomicity)和一致性(Consistency)的区别?
原子性(Atomicity)和一致性(Consistency)是数据库事务ACID特性中的两个核心概念,虽然它们密切相关,但解决的问题和侧重点完全不同。原子性关注事务的操作完整性,而一致性关注数据的逻辑正确性。…...
windows设置暂停更新时长
windows设置暂停更新时长 win11与win10修改注册表操作一致 ,系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值,名称为FlightSettingsMaxPauseDays 根据需求填写数…...
【Kimi】自动生成PPT-并支持下载和在线编辑--全部免费
【Kimi】免费生成PPT并免费下载 用了好几个大模型,有些能生成PPT内容; 有些能生成PPT,但下载需要付费; 目前只有Kimi生成的PPT,能选择模板、能在线编辑、能下载,关键全部免费! 一、用kimi生成PP…...
一款在手机上制作电子表格
今天给大家分享一款在手机上制作电子表格的,免费好用的Exce1表格软件,让工作变得更加简单。 1 软件介绍 Exce1是一款手机制作表格的办公软件,您可以使用手机exce1在线制作表格、工资表、编辑xlsx和xls表格文件等,还可以学习使用…...
【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.3.1单节点安装(Docker与手动部署)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 10分钟快速部署Elasticsearch单节点环境1. 系统环境要求1.1 硬件配置推荐1.2 软件依赖 2. Docker部署方案2.1 部署流程2.2 参数说明2.3 性能优化建议 3. 手动部署方案3.1 安…...
7 天精通 DeepSeek 实操手册
挑战目标 从零基础开始,用 7 天时间,精通 DeepSeek 实操。 对零基础的同学来说,要全部完成这个挑战并不容易。因此,我们提供了每天的学习目标和实操任务,并提供三大锦囊助你一臂之力: 针对常见问题的解决…...
过滤器 二、过滤器详解
过滤器生命周期: init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法…...
【Mac电脑本地部署Deepseek-r1:详细教程与Openwebui配置指南】
文章目录 前言电脑配置:安装的Deepseek版本:使用的UI框架:体验效果展示:本地部署体验总结 部署过程Ollama部署拉取模型运行模型Openwebui部署运行Ollama服务在Openwebui中配置ollama的服务 后话 前言 deepseek最近火的一塌糊涂&a…...
网络安全学习中,web渗透的测试流程是怎样的?
渗透测试是什么?网络安全学习中,web渗透的测试流程是怎样的? 渗透测试就是利用我们所掌握的渗透知识,对网站进行一步一步的渗透,发现其中存在的漏洞和隐藏的风险,然后撰写一篇测试报告,提供给我…...
将VsCode变得顺手好用(1
目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹,用于放置调试文件以及你未来写的代码,随便命名但…...
【MySQL篇】表的操作
1,创建表 语法: create table ( field1 datatype, field2 datatype, field3 datatype )charset 字符集 collate 校验规则 engine 存储引擎; 说明: field表示列名datatype表示列的类型charset字符集,如果没有指明,则…...
第6_7章_管理权限评估和测试策略
管理权限 权限将受保护的对象与必须评估以决定是否应授予访问权限的策略相关联。 在创建要保护的资源以及要用于保护这些资源的策略后, 您可以开始管理权限。要管理权限,请在编辑资源服务器时单击 Permissions 选项卡。 可以创建权限来保护两种主要类…...
2025年网校系统源码开发趋势:技术革新的教育培训APP搭建实战
2025年,随着AI、大数据、云计算等技术的深度融合,网校教育系统的源码开发也迎来了新的发展趋势。本文将深入探讨这些趋势,并结合教育培训APP的开发实战,展示如何应对未来的技术挑战。 一、2025年网校教育系统源码的技术趋势 AI驱…...
Linux驱动开发实战(一):LED控制驱动详解
Linux驱动开发野火实战(一):LED控制驱动详解 文章目录 Linux驱动开发野火实战(一):LED控制驱动详解引言一、基础知识1.1 什么是字符设备驱动1.2 重要的数据结构read 函数write 函数open 函数release 函数 二…...
PowerShell 执行策略:fnm管理软件安装nodejs无法运行npm,错误信息:about_Execution_Policies
通过fnm管理软件安装NodeJS后添加环境变量依然无法执行npm,提示无法加载文件,错误如下: PowerShell 执行策略简介: PowerShell 执行策略是一项安全功能,用于控制 PowerShell 加载配置文件和运行脚本的条件。 此功能有助于防止恶…...
论文阅读笔记:Deep Face Recognition: A Survey
论文阅读笔记:Deep Face Recognition: A Survey 1 介绍2 总览2.1 人脸识别组件2.1.1 人脸处理2.1.2 深度特征提取2.1.3 基于深度特征的人脸对比 3 网络结构和损失函数3.1 判别损失函数的演化3.1.1 基于欧式距离的损失3.1.2 基于角度/余弦边距的损失3.1.3 Softmax损失…...
本地dify绑定notion
需要用到 notion 的“集成”功能。对于个人用户来说,选择使用**内部 internal **集成,公司用户可以考虑使用公开 public 集成。 在下面的 notion 集成网站中申请一个新的集成: Notion – The all-in-one workspace for your notes, tasks, …...
k8s中pod的调度策略之pod的亲和性调度与反亲和性调度 一文搞懂 k8s中创建的pod如何调度?
接上文写的Node亲和性调度https://blog.csdn.net/soso678/article/details/144777397 Pod 间的亲和性和反亲和性(Affinity/AntiAffinity)调度 Pod 间亲和性与反亲和性使你可以基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到的节点࿰…...
JSON Schema 入门指南:如何定义和验证 JSON 数据结构
文章目录 一、引言二、什么是 JSON Schema?三、JSON Schema 的基本结构3.1 基本关键字3.2 对象属性3.3 数组元素3.4 字符串约束3.5 数值约束 四、示例:定义一个简单的 JSON Schema五、使用 JSON Schema 进行验证六、实战效果6.1 如何使用 七、总结 一、引…...
借DeepSeek的风思考:未来可通过AI+视觉识别技术,实现足球比赛中的教练决策指挥系统,以此提高中国足球冲出亚洲夺取世界杯冠军
国家如此强大,必须需要提升国足冲向世界,一雪前耻的了。现在我脑洞大开,提出以下思路寄望国家重视。具体思考如下: 通过AI视觉识别技术实现足球比赛中的教练决策指挥系统,有潜力提升中国足球的竞争力。但要实现这一目标…...
DeepSeek今日连开3源!针对优化的并行策略,梁文锋本人参与开发
DeepSeek开源周第四天,直接痛快「1日3连发」,且全都围绕一个主题: 优化并行策略。 DualPipe:一种创新的双向流水线并行算法,能够完全重叠前向和后向计算-通信阶段,并减少“流水线气泡”。它通过对称的微批…...
【含文档+PPT+源码】基于过滤协同算法的旅游推荐管理系统设计与实现
项目介绍 本课程演示的是一款基于过滤协同算法的旅游推荐管理系统设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套…...
蓝桥杯2024年第十五届省赛真题-传送阵
#include<stdio.h> #include<stdbool.h> #define MAX 100000 int circle[MAX];//记录每个环大小 int parent[MAX];//记录每个传送阵所属的环 int m[MAX]; bool visited[MAX]; int circleIndex0;//当前环的编号 //迭代实现换的查找void findcircle(int start){int c…...
