自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(47)
  • 收藏
  • 关注

原创 链表面试题9之环形链表进阶

本文讨论了如何利用双指针算法解决环形链表问题,特别是如何找到环形链表的入口节点。文章首先回顾了使用快慢指针判断链表是否为环形的基本方法,然后进一步探讨了在已知链表为环形的情况下,如何确定环的入口节点。通过数学推导,文章解释了为什么从头节点和相遇点同时出发的两个指针,以相同的步长移动,最终会在环的入口节点相遇。此外,文章还提供了相应的C语言代码实现,并分析了算法的时间复杂度和空间复杂度。最后,文章强调了理解算法思路的重要性,并鼓励读者通过实践逐步掌握这一技巧。

2025-05-20 23:10:17 6026 27

原创 链表的面试题8之环形链表

文章主要讨论了如何利用双指针技巧解决链表中的常见问题,特别是判断链表是否存在环。首先,文章通过两个例子(获取倒数第k个元素和获取中间元素)介绍了双指针的基本应用。接着,文章详细解释了如何利用快慢指针判断链表是否存在环:快指针每次移动两步,慢指针每次移动一步,如果链表有环,快指针最终会追上慢指针,从而证明环的存在。文章还探讨了快指针移动步数多于两步的可行性,并提供了相应的代码实现。最后,文章鼓励读者通过理解思路来掌握双指针技巧,并提供了进一步学习的建议。

2025-05-20 20:10:53 6257 17

原创 链表面试题7之相交链表

来了来了,这道题才是值得我们奇思妙想的题,链接在下面。看完题目一脸懵吗,没关系,我们还得看示例还是一脸懵怎么办??两个链表相交的方式有几种?我们再来仔细看一下这道题这里我们就看到了,可能出现三种形式的相交,那我们就要在想一下,这三种情况下,我们应该怎么去判断这两个链表是相交的。为什么是找地址而不是比值呢?好了,那我们来试试看,能不能用双指针法来解决,但是你会很直观发现不可行,因为链表长度是不相同的。那怎么解决呢?那我们就要找两个链表的长度差了,这里不是链表长短不一样阻碍了我吗?

2025-05-12 21:25:20 5641 36

原创 链表面试题6之回文结构

当然是不可以的,因为链表的物理结构就规定了,链表只能从头开始遍历。注意,这里的空间复杂度已经是O(n)了,嗯?那么我们想到这里的话,也自然会想到,我现在的难点是尾端无法向前遍历,有什么办法能让我从尾端向前面遍历呢?但是我这里已经明确给出了链表长度不超过900,而我不在乎空间的浪费,就定义为a[900]。这是常数,下面是两种情况会给出O(n)的空间。我们在动态数组的时候就是O(n),是空间会随着你所给数据的多少而扩容不确定的才会是O(n)经过前几道题的铺垫,那么我们也是来到了链表的第六关。

2025-05-12 20:50:09 391 23

原创 链表面试题5之链表分割(拓展必看!)

欧克,这篇文章我们就要上强度了。这道题非常简洁啊,太好了,说明这是一道比较抽象的题目。但是这道题目被标为了较难题,难在哪里?足足跨过了一个中等的界限。没有测试案例,这一切都是未知的,那么我们就需要自己去考虑所有的边界情况。第一种办法:双链表法(哑节点辅助)思路:创建两个哑节点作为小链表和大链表的头,遍历原链表,将节点分别添加到对应链表的尾部,最后合并。时间和空间复杂度都是O(n),但空间复杂度是O(1)(只使用几个指针)。首先讲一下什么是哑巴节点,和我们常说的哨兵位头节点又有什么区别。

2025-05-08 20:18:31 896 8

原创 链表的面试题4之合并有序链表

这篇文章我们继续来讲链表中很经典的面试题:合并有序链表。我们首先来看一下这张图片里面的要求,给你两个链表,要求把他们按照从小到大的方式排列。这里涉及到几个问题,好了,不多说了,再说就要被自己绕晕了哈哈,初学者就是不需要想很多,遇到链表的题,无非三种路径,双指针,迭代,递归。我们先来看好理解的迭代的方法。当然这道题的双指针和迭代其实也是殊途同归。本质上是一样的。

2025-05-08 15:46:21 670 4

原创 链表的面试题3找出中间节点

来来来,接着继续我们的第三道题。这道题的话,思路是非常明确的,就是让你找出我们这个所谓的中间节点并且输出。那这道题我们就需要注意一些细节上的问题,或者说是对于整个链表结构的访问的理解要到位。如果这道题放在顺序表上,那我们很容易就能根据下标来判断是否为中间节点。但是,问题就出在,链表是不能依据数组下标来访问的,那这道题我们很简单的思路就是,先得出链表长度,再定义变量值来求中间节点。那我把代码贴在下面。

2025-05-06 23:05:20 285 1

原创 链表的面试题2反转单链表

好,我们接着来看第二题。

2025-05-06 19:48:16 440

原创 链表的面试题1

本题还可以采用栈去做。将值不等于 val 的节点依次压入栈中;将压入栈的节点重新连接,栈底的节点作为新的头节点返回。为什么要压栈?因为迭代压栈的效率比递归高,没有函数调用的开销。当然我们在这里如果严谨一点说的话,显式栈结构还是比较复杂的,空间复杂度是O(n)。除此之外,需要手动维护栈结构,代码比递归实现更复杂。好了,以上就是主流的五种方法了,希望对你有所收获。一步步来,总会学会的,首先要懂思路,才能有东西写。

2025-05-04 16:49:43 1044 2

原创 让天底下没有难学的链表2(回归超长加更学习爆爽篇)

好了,那么上一篇文章我们大概了解了链表的性质以及基本结构这里我们复习一下:1.链表在逻辑结构上是连续的 , 在物理结构上不连续2.结点一般是在堆上申请的3.从堆上申请来的空间 , 是按照一定策略分配出来的 ,每次申请的空间可能连续 , 可能不连续。那么这篇文章,我们就来具体探讨一下,如何手搓一个链表,以及链表的具体步骤有哪些。

2025-05-04 15:29:29 866

原创 让天底下没有难学的链表1

上篇文章,我们详细地逐字逐句的讲解了顺序表的创建及其使用。想必大家对于顺序表使用的一个内部思路都已经非常清楚了,但是我们也讲过,顺序表存在一些不足这里再给大家贴一下。1. 中间/头部的插入删除,时间复杂度为O(N)2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。那么今天我们就正式进入正题:链表。

2025-03-11 15:42:26 582 1

原创 小白也爱看的数据结构(顺序表完结)

时间紧,任务重。我们直接开始。我看了一下上一篇文章的具体的讲解,需要上下翻看很不容易,这篇文章,我就会以注释的形式写在代码里,必要的细节再给大家讲解。当然相比于前面的代码,现在的一各个函数就是洒洒水啦。

2025-03-09 16:15:35 242

原创 小白也爱看的数据结构(顺序表)

本文的顺序表和链表两者异曲同工,读者在阅读学习的时候可以自己亲身体会一下两者各有什么差距,可能有读者会说,在后续c++的库里面都可以直接用,只要大致了解,但是,实际上,没有数据结构的了解,我们很难真正意义上将这个函数或者代码运用到极致。看到这,你可以狭隘地理解为,差距就是体现在动态数组的创建上,从而引发的一些访问与输出的问题,当然根据我们所知的知识,肯定也会影响我们的时间复杂度和空间复杂度。下面是标准版的顺序表的格式,这里的格式就会显得非常的呆板。但是基本的插入又分为头插和尾插,删除也分为头删和尾删。

2025-03-09 15:45:27 851 1

原创 小白也爱看的初阶数据结构2

好了,讲到这里复杂度基本都讲完了,下一篇文章我们就来讲解顺序表,如果你看到了这里,那你真的很棒。

2025-03-08 18:04:52 949

原创 小白也爱看的初阶数据结构1

好了,从今天开始我们就正式进入到了初阶数据结构的范畴,在此之前我还是先跟大家说一下前言,了解一下数据结构。大家在学习的时候才能更加有动力和激情。

2025-03-08 17:24:57 835

原创 那些不为人知的文件操作知识2

朋友们,承接上文。我上篇文章发布出去的时候想到缓冲区的内容忘记讲了,不过没关系,放在这一篇文章里面更加能体现内存空间的变化。缓冲文件系统文件缓冲区文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。具体的方式如下,这个就像我们在使用printf的时候所标注的%d这种是一样的意义。这个代码比较简单,不做过多解释,可以放在ai里面自己去尝试理解,主要要理解这个逻辑。上面是c++的网站,这里解释一下什么是输入输出流。

2025-03-07 22:13:50 980 1

原创 那些不为人知的文件操作知识1

好了朋友们,这将是我们在c语言知识的最后一节课,正如题目所言,关于文件的各种知识,你可能或多或少的听过,但一定没有系统性的学习过,比如文件的后缀.c文件和txt文件为什么是这样,好,今天这篇文章我们就来深入的讲解。如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。这里我们讨论的是数据文件。

2025-03-07 21:17:49 1097

原创 非常重要的动态内存错误和柔性数组2

在 free(str) 之后,str 指向的内存已经被释放,但后续代码仍然尝试使用 str(如 strcpy 和 printf),这会导致未定义行为。这里很明显就能看到,这里引用的函数名是不匹配的。然后这里printf的打印是不标准的,有些编译器可能会让你通过,当然有些就已经报错了,程序不稳定,有安全风险。但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁。实际上普通的局部变量是在栈区分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。

2025-03-06 20:00:36 1129

原创 非常重要的动态内存错误和柔性数组1

因此,GetMemory 返回的指针指向一个无效的内存区域,导致 Test 函数中的 printf 操作会引发未定义行为(表现通常是打印乱码或程序崩溃)。承接上次的动态内存的分享,我想想还是把具体的易错点分享一下,再跟大家分享四道非常经典的笔试题,以后找工作会发现,很多题就是这四道题的原型。这个后面两篇文章会讲。在 Test 函数中,str 被初始化为 NULL,但通过 GetMemory 赋值后,它指向了一个无效的内存地址。程序分配了内存但没有释放,导致内存被持续占用,最终可能导致系统内存耗尽。

2025-03-06 19:34:08 663

原创 小白也能看懂的深度学习7

还是用原本视频的例子最为贴近来解释关于广播的矩阵算法。这是一个不同食物(每 100g)中不同营养成分的卡路里含量表格,表格为 3 行 4 列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。那么,我们现在想要计算不同食物中不同营养成分中的卡路里百分比。 现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和 56+1.2+1.8 = 59,然后用 56/59 = 94.9%算出结果。 可以看出苹果

2025-03-04 16:24:25 981

原创 小白也能看懂的深度学习6

它的假设函数是sigmoid函数,也就是hθ(x) = 1/(1 + e(-θT x)),这里的θ是参数向量,x是特征向量。如果是非向量化的方式,也就是逐个样本计算的话,梯度下降的更新规则可能是这样的:对于每个θ_j,计算梯度项,然后累加所有样本的梯度,再取平均,然后乘以学习率α,最后用这个来更新θ_j。比如,对于所有样本,梯度的计算可以表示为X的转置乘以(h - y)然后除以m,也就是 (1/m) * X^T (h - y),其中h是sigmoid(Xθ)的结果。这里的求和是对所有样本i=1到m进行的。

2025-03-04 15:44:06 359 1

原创 小白也能看懂的深度学习5

从这幅图中也不难见得我们的意图,本质上,我们就是将一连串的数据变成了一些行向量和列向量,再通过矩阵化的乘法,从而对一组数据进行计算训练,比显性的for循环快速很多。前向传播是训练和推理过程中必不可少的步骤。它可以让 python 的充分利用并行化计算,这是事实在 GPU 和 CPU 上面计算,GPU 更加擅长 SIMD 计算,但是 CPU 事实上也不是太差,可能没有 GPU 那么擅长吧。现”,但是我做的所有的案例都是在 jupyter notebook 上面实现,这里只有 CPU,CPU 和 GPU。

2025-03-03 18:00:42 769

原创 小白也能学会的深度学习4

我们上面刚讲了,我们要让损失函数尽可能的小,或者说,我们要让损失函数算出来的值尽可能的靠近实际值,而且还要把我们的成本降到最低,在这里面,训练集的选择就变得至关重要了。值得一提的是损失函数是在单个训练样本中定义的,它衡量的是算法在单个训练样本中表现如何,为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数,算法的代价函数是对m个样本的损失函数求和然后除以m,这就是一个非常明确的目的。大家好,上篇文章我们讲了逻辑回归的模型,也知道逻辑回归的成本是很高的,我们需要去 不断的优化再优化。

2025-03-03 17:16:52 274

原创 一看就懂的动态内存管理2

好了承接上文,我们来讲。

2025-03-02 15:03:58 1047

原创 一看就懂的动态内存管理1

这时候就只能试试动态内存开辟了。什么意思呢,就是我们系统开辟内存的时候分为三个区域,一个是栈区一个是堆区,而我们的动态内存就是在堆区上开辟的,包括图里面的四个动态内存函数也都是在堆区上用的。malloc 是 "memory allocation" 的缩写,用于在堆上分配指定大小的内存块,并返回指向该内存块的指针。好这篇文章我们就来看看动态内存的管理,这篇文章的知识就涉及到栈帧的的创建和数据结构方面的知识了,换句话说,也是在。如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。

2025-03-02 14:13:52 380

原创 看完就进阶的结构体完结篇4枚举和联合

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。//联合类型的声明union Unchar c;int i;//联合变量的定义//计算连个变量的大小。

2025-03-01 19:53:25 701

原创 看完就进阶的结构体完结篇3位段

承接上文,讲完了结构体我们就得来讲讲位段。位段(Bit Field)已经涉及是C/C++语言中的一种数据结构,它允许你在结构体或联合体中定义特定宽度的字段。位段的主要用途是节省内存空间,特别是在嵌入式系统或对内存使用有严格限制的应用中。什么是位段位段的声明和结构是类似的,有两个不同:1.位段的成员必须是 int、unsigned int 或signed int。2.位段的成员名后边有一个冒号和一个数字。在这里A就是一个位段类型那位段A的大小是多少?怎么计算呢?

2025-03-01 19:19:43 1131

原创 看完就进阶的自定义2

有了结构体类型,那如何定义变量,其实很简单int x;int y;}p1;//声明类型的同时定义变量p1//定义结构体变量p2可以直接在花括号后面跟定义,也可以单独定义。那初始化呢?//初始化:定义变量的同时赋初值。struct Stu //类型声明//名字int age;//年龄//初始化直接赋值初始化。或者嵌套初始化int data;//结构体嵌套初始化//结构体嵌套初始化结构体内存对齐我们已经掌握了结构体的基本使用了。现在我们深入讨论一个问题:计算结构体的大小。

2025-02-26 20:06:46 492 1

原创 自定义类型看完这篇就进阶1

这篇文章我们来讲讲所谓的自定义类型。自定义类型:结构体,枚举,联合首先我们先来看结构体。可以说,结构体这块知识你学通透了,后面的枚举和联合将不攻自破了。

2025-02-26 19:29:02 845 2

原创 小白也能学会的深度学习3

我们用w来表示逻辑回归的参数,这也是一个维向量(因为w实际上是特征权重,维度与特征向量相同),参数里面还有b,这是一个实数(表示偏差)。对于二元分类问题来讲,给定一个输入特征向量x,它可能对应一张图片,你想识别这 张图片识别看它是否是一只猫或者不是一只猫的图片,你想要一个算法能够输出预测,你只能称之为y^,也就是你y的估计。例如有一个包含x个样本的训练集,你很可能习惯于用一个 for 循环来遍历训练集中的每个样本,但是当实现一个神经网络的时候,我们通常不直接使用 for 循环来遍历整个训练集。

2025-02-24 16:09:55 390 1

原创 小白也能看懂的深度学习2

可以知道的一个使用 sigmoid 函数和机器学习问题是,在这个区域,也就是这个 sigmoid 函数的梯度会接近零,所以学习的速度会变得非常缓慢,因为当你实现梯度下降以及梯度接近零的时候,参数会更新的很慢,所以学习的速率也会变的很慢,而通过改变这个被叫做激活函数的东西,神经网络换用这一个函数,叫做 ReLU 的函数(修正线性单元),ReLU 它的梯度对于所有输入的负值都是零,因此梯度更加不会趋向逐渐减少到零。有些人会说,音频这些东西,我们人类是很容易使用的,或者说,最先开始使用的就是非结构化数据。

2025-02-24 15:31:08 1019

原创 字符函数和字符串函数3完结篇

上一篇文章讲了长度受限制的字符串函数介绍strncpystrncatstrncmp以及字符串查找的两个函数strstrstrtok今天这篇这个文章就是这个系列的完结了,接下去的是动态内存管理和结构体的内容,后面就转到用c语言的初阶数据结构了。

2025-02-22 14:53:10 1055

原创 字符函数和字符串函数2

接续上文,我们讲了求字符串长度的strlen还有长度不受限制的字符串函数strcpystrcatstrcmp那么本篇我们就继续来讲长度受限制的字符串函数。

2025-02-22 07:00:00 790

原创 字符函数和字符串函数1

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组里字符串常量适用于那些对它不做修改的字符串函数.

2025-02-21 12:28:47 804

原创 小白也能看懂的深度学习 第一门课1

我们知道深度学习是指训练神经网络的过程。但是有时它指的是特别大规模的神经网络训练。这里就举了一个例子。我们想探讨房子大小和房价的关系。那么我们就要有一个计算的公式,但是在这之前,我们得知道这个公式是怎么形成的,也就是拟合函数。如果是直线,那就是一个一次函数。那就会出现下面这张图。这就是高中学的线性回归,也就是经验回归,通过我的样本数去看,什么因素大概影响我的房价,最终确定下来这个值,那就形成了一个固定的函数了。

2025-02-21 07:00:00 346

原创 细到极致的操作符(3)

代码二此处if (a =b + 1, c=a / 2, d > 0)代码是错误的,代码中`d`未定义,不过仅从已有正确部分看,先执行`a =b + 1`(此时`a`被赋值为`2 + 1 = 3`),然后执行c=a / 2(`c`被赋值为`3 / 2 = 1`,因为是整型除法),但由于`d`未定义所以是无法判断整体`if`条件是否成立的。逗号表达式,就是用逗号隔开的多个表达式。先计算`a>b`,此时`a = 1`,`b = 2`,`a>b`为假(值为0),但这个结果在逗号表达式中会被丢弃。

2025-02-20 07:00:00 784

原创 细到极致的操作符(4)必看篇

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。如果我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。这里列一下这个东西,如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长。

2025-02-20 07:00:00 1246

原创 细到极致的操作符(2)

这里要注意的是sizeof后面必须要加上括号,不然就会出错。赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。这里自己去运行一下就会发现,sizeof返回的是整个数组的大小,也就是整个数组的字节数。当然这里要提一下,赋值操作符是可以连续使用的。这些关系运算符比较简单,没什么可讲的,但是我们要注意一些运算符使用时候的陷阱。知道复合使用的逻辑和知道原来这个是可以复合的就基本差不多了。警告: 在编程的过程中== 和=不小心写错,导致的错误。-- 前置、后置--

2025-02-19 17:58:44 254

原创 细到极致的操作符知识点(1)

虽然很难理解,但是我还是放出来,你只需要知道的是这会极大的方便程序员的位级别的运算,同时也可以进行快速乘除。想了很久还是想分享一下c语言里面的操作符,这篇文章的操作符和其他不一样,就像标题所说,细到极致,别人没有的这里都有!这个移位操作主要是对于二进制的整数进行的一个,平常一般不会用,一般都在按位异或或者计算2的高次幂的时候能更加高效。想不到是正常的,学的越多越想不到,所以每一个部分基础都要打好,这可是一道面试题,想想有多变态吧,难倒一片。如果你是挣扎着做出的,那恭喜你,你一定印象很深刻了。

2025-02-19 17:30:33 384

原创 函数看完这篇就登峰造极第四部分,迭代

首先,在这里放一个递归的自定义函数,这里解释一下,谁的阶乘就是,从1一直加一到你这个数的所有数的乘积。那么也就意味着你这个数一定是多变的,如果你的n取到了很大的数,那很麻烦。等于第三项就单独拎出来算了两遍,但是以此类推,如果这个n很大的时候,比如50,就会具有一个特别大的计算量,程序运行的时间就会变得很长。这里给大家贴一个代码,大家直接复制粘贴去运行一下就会发现,这是千万级的计算量,就50为例的时候,但是50肯定不能满足我们,这就说明这个代码的效率实在是太低了。这就涉及到了函数栈帧的创建了,这里是栈溢出。

2025-01-15 22:11:06 589

oj上题目的讲解,这里给大家总结了一下四大排序基本语法框架

一题多解,知识脉络由浅到深,给人警醒,给新手小白了解四大升序排序方法的保姆式讲解和批注,附加图讲解,自己动手按照注释来演示一遍,马上就能学会!

2024-11-11

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除