自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++:拷贝构造函数

然后s2对象使用s1拷贝构造,而Stack类中没有显式定义拷贝构造函数,则编译对象会给Stack类生成一份默认的拷贝构造函数,默认拷贝构造函数是按照值拷贝的,即将s1中内容原封不动的拷贝到s2中,连指针的值也拷贝了,因此s1和s2指向了同一块内存空间;当程序退出时,s2和s1要销毁,s2先销毁,s2销毁时调用析构函数,已经将0x11223344的空间释放了,但是s1并不知道,会将该空间再释放一次,一块内存空间多次释放,肯定会造成程序崩溃。那在创建对象的时候,可否创建一个与已存在对象一模一样的新对象呢?

2024-03-07 17:48:05 458 1

原创 搜索(3):双向BFS

对于一些问题我们使用普通BFS求解时,队列中最多会存在两层的搜索节点,搜索空间的上界取决于目标节点所在的搜索层次的深度所对应的宽度,一旦层数比较多,那可能会出现搜索爆炸的问题,双向BFS可以让我们不使用这么宽的搜索空间,这可以保证搜索到目标结果。

2024-01-25 21:53:55 472

原创 搜索(2):宽度优先搜索

从起点开始,先将起点入队并标记,之后开始宽搜,每次将队首元素出队,搜索它的周围元素,如果没有走过则进行标记,这是判重,因为之后再到这个位置的步数肯定比之前要多,所以我们标记之后就不会再搜索这个位置,然后将存步数的数组对该位置加1,之后将其压入队中,这是向外辐射扩散的。对于最少步数的问题,我们建的图存的是到达该位置的最少步数,而队列的结构体元素存的是图中每个点的坐标,并进行判重。宽搜的过程,通过队列来维护序列的状态空间,入队就排队等待,出队就将儿子们入队。宽搜的计算:出队后,入队前,结束后。

2024-01-23 19:23:06 747 4

原创 搜索(1):深度优先搜索

今天主要来了解深度优先搜索(DFS)。

2024-01-22 19:59:54 2010 1

原创 蓝桥杯(一)

巧妙之处在于操作的顺序是无关紧要的,先删除两个最小的宝石、再删除最大的宝石和先删除最大的宝石、再删除两个最小的宝石的结果是一样的。假设删除了两个最小宝石的操作次数为m,当我们删除两个最小宝石的时候,剩下的宝石就是从中删除了2m个最小宝石和(k-m)个中最大宝石的宝石数组。计算每张牌反面和正面的点数之差d,如果d>0,则反面点数大于正面,可以翻转;如果能交换位置,自然比替换更有效,所以如果不互补,我们先找能够交换碱基的两个位置,找到了就交换,计数器加1,其他情况直接对计数器加1即可。

2024-01-10 19:44:15 842 1

原创 leetcode:滑动窗口

这道题让我们求最大的问题,而且是连续非空的子数组,很容易想到滑动窗口,但滑动窗口有定长和不定长两种,题中说长度为k,说明是定长的,要求长度为k的几乎唯一子数组的最大和,我们可以先求前k-1个数,这样之后进来一个出去一个,始终是k个数,题目要求该子数组至少有m个不相同的数,我们怎么记录是否有m个不相同的数呢?,我们如果维护两个窗口的和,使得和等于x肯定是很麻烦的,那不如我们只维护一个窗口,这个窗口的和要等于整数数组nums的和sum-x,这样只用维护一个区间,不得不说,这个思维太帅了。这道题借用灵神的思路,

2024-01-08 14:09:01 890 12

原创 二叉树常见题型(1)

做二叉树的题目最常见的做法就是递推和迭代,而一般我们更青睐递推,在我们写递推的时候,我们,我们只需要,你想一步一步的把递推的细节过程想明白?这难道不是很麻烦吗?只要边界条件和单层逻辑没有问题,结果也是没问题的,这也是数学归纳法的逻辑。

2024-01-07 13:33:46 1074 4

原创 数据结构:二叉树

树是计算机数据存储的一种结构,因为存储类型和现实生活中的树类似而被称为树。树的源头称为根,其余分叉点称为节点,而起始的分叉点被称为根节点,树的尽头是叶,我们称之为叶节点。每一个节点的起点被称为父节点,由父节点衍生出去的节点称为子节点,没有父节点的节点为根节点,没有子节点的节点称为叶节点,共用一个父节点的节点为兄弟节点。树的高度从下往上看,深度则是从上往下看,层数等于高度+1。

2024-01-06 21:13:06 1133 2

原创 C++:类和对象(3)

因为我们写下了Person p,没有参数,要调用系统或者用户提供的无参构造函数,但因为我们实现了有参构造函数,系统就不会提供无参构造函数,同时我们自己也没有实现无参构造函数,就会报错。可以看出,当我们自己实现了拷贝构造函数,如果我们自己不实现无参构造函数,系统就不会提供,有参构造函数系统本来就提供不了。p1和p2的指针都指向同一块空间,同一块空间释放两次肯定是不允许的,所以报错意料之中,浅拷贝带来的问题就是。那我们就有问题了,当我们创建B的对象时,A和B的构造函数和析构函数先执行谁的呢?

2024-01-06 11:21:07 528 2

原创 数据结构:STL:queue stack

queue的定义和vector没什么不同queue变量名;类型可以是int,double等基本数据类型,也可以是自定义的结构体,也可以是STL容器。stack变量名;类型可以是int,double等基本数据类型,也可以是自定义的结构体,也可以是STL容器。

2024-01-05 11:12:29 907 2

原创 C++:类和对象(2)

在生活中我们购买电子产品都会有出厂设置,我们如果不用了也要删除信息保证自己的隐私安全,C++的面向对象来源于生活,每个对象也会有初始化设置以及对象销毁前的清理数据的设置。可以发现,我们只是创建了一个对象,并没有实现函数,这肯定是构造函数和析构函数被系统自动调用了啊,这两个函数都是必须有的,如果我们自己不提供,编译器给你提供,但都是空实现。如果我们自己不实现这两个操作,编译器会提供,但编译器提供的构造函数和析构函数是空实现。解决问题,这两个函数被编译器自动调用,完成对象的初始化和清理工作。

2024-01-04 22:12:21 649 4

原创 数据结构:STL:vector

定义容器和定义变量没什么区别vector<类型名> 变量名;类型可以是int、double、char、struct,也可以是STL容器:vector、set、queue等等。vector数组是一个一维数组,如果定义成vector数组的数组,那就是二维数组。//二维变长数组。

2024-01-04 15:27:51 1017 1

原创 基础算法(8):高精度加减乘除

为什么要有这么一种算法?因为当我们想需要对两个很大的数进行运算,比如38149194919814894819+89198481314819,结果很显然超出了int范围能表示的整数,我们这时候就要用到高精度算法,高精度算法通过用。

2024-01-02 15:40:56 767 3

原创 数据结构:队列(链表和数组模拟实现)

我们首先创建一个值为data的队列节点vtx,如果队尾非空,则将vtx作为队尾元素的后继,否则将队首元素置为vtx,队尾元素变成vtx,队列的长度加一。我们将队首元素缓存到temp中,将当前的队首变成temp的后继,释放temp的内存,队列长度减一,如果此时队列为空,则将队尾置为空。我们用链表来模拟每个队列元素,可以用链表节点来表示,data是数据域,next是指针域。队列也是一种数据结构,队列和栈不同的是,栈是先进后出,而。,这跟我们平时排队是一样的,先排的先办完事走,后排的后走,队列又被称为。

2024-01-01 23:01:40 893 1

原创 基础算法(7):离散化和区间合并

这个函数把一个序列的重复数据从小到大放在序列末尾,并返回重复数据的第一个数据的迭代器。这道题数据的值域已经达到了10^9,远远比10^5大,所以前缀和是用不了的,我们要使用离散化。如果我们想要把这些数作为数组的下标来存储的话,我们就要开辟一个很大空间的数组,但很显然,其中很多空间我们是用不到的,浪费的不是一星半点,我接受不了,题目也不会让你过。区间合并也是一种算法,主要用来合并区间,没错,就是这么简单粗暴,下面先给出模板,结合例题来领悟这种算法。

2024-01-01 19:12:56 555 1

原创 洛谷:集合与差分

如果城市的名称和洲的名称不一样,再执行之后的操作,如果m[a+b]是0,说明之前没有出现,ans+=0;,我们先构造差分数组,因为d[i]=a[i]-a[i-1],所以我们对差分数组加上一个数,也会对原数组每个元素加上一个数,但由于区间外的不能改变,所以我们对区间外再减去一个数,最后恢复原数组1即可。这道题要对一个矩形区域内的加上一个数,就是差分二维化,要注意的是最后恢复原数组时,因为原数组是差分数组的前缀和,所以差分数组相加等于原数组,我们直接对差分数组进行操作就可以。

2023-12-31 19:27:16 634 1

原创 洛谷:集合与前缀和

这道题其实和上一道是基本上一样的,唯一不同的是这道题当两个人是敌人的时候我们怎么进行记录,是朋友就把把两个集合合并,如果是敌人,我们定义一个二维数组,如果p和q是敌人,则rsp[p][q]=rsp[q][p]=1,表示两个人是敌人, 当我们遍历时,如果q和j或者p和j是敌人,那p和j或者q和j就是朋友,合并两个集合即可,最后统计出有多少个集合,返回cnt。给一个单词,我们就知道它在哪篇文章出现过,而且还不只一篇文章,对应的值是一个集合,那我们的思路就很清晰了。

2023-12-29 21:36:15 501 3

原创 洛谷:线性表

啊,如果定义在主函数里面而且你不初始化,数组里面就全是随机值,因为这个卡了一些时间,

2023-12-28 19:58:14 1007 4

原创 通讯录管理系统简单实现

今天我们要实现的通讯录管理系统主要有7项功能:添加联系人,显示联系人,删除联系人,查找联系人,修改联系人,清空联系人,退出通讯录。

2023-12-27 20:08:23 450 2

原创 数据结构:单调栈

给定一个温度序列,让你求每个温度离它最近的比它高的温度是之后第几天,显然符合单调递增栈的特征,我们定义一个栈stk来存储每个温度对应的下标和存储结果的vector数组res,从头开始遍历,如果栈为空或者栈顶下标对应的温度大于当前温度值,则当前温度对应的下标入栈;假如我们现在有一个序列10,2,8,5,13,我们要找每个数离它最近的比它大的数,我们要构造一个单调递增的栈,则如果栈为空或者入栈的元素大小小于栈顶值,就入栈,否则入栈会破坏栈的单调性,这时候比入栈元素小的元素全部出栈。单调递减栈的原理和递增类似。

2023-12-27 12:50:26 836 1

原创 基础数论二:分解质因数、筛质数

埃氏筛法基本思路是:首先将2到n范围内的整数写下来,其中2是最小的质数,将表中所有的2的倍数的数划掉,然后就是3,3是质数,把表中所有3的倍数的数划掉.....依次类推,如果表中剩余的最小的数是n,那么n就是质数,然后再把表中所有m的倍数的数划去,反复进行,就能筛出2到n的所有质数。st[]用来判断遍历到的数是否被划掉,如果st[i]=false,说明i是i到n最小的质数,添加到primes中,然后就把所有i的倍数的数划掉,令st[j]=true,来说明j已经1被划掉;只有一个质因子的正整数为质数。

2023-12-26 23:31:41 570 1

原创 数据结构:Trie树(字典树)

此时p=1,指向a这个节点,判断son[1][1]是否存在,发现没有这个子节点,进行插入,即son[1][1]=++idx=2,表示下标为1的节点a有一个子节点,存储字符b,这个子节点的下标为2。接着我们就要找是否存在根节点的子节点,这个子节点存储了字符a,很显然是没有的,所以我们就要插入字符a,就是son[0][0]=++idx,son[0][0]就表示0这个下标为0的根节点有一个子节点,存储字符a,这个子节点的下标为1;然后就令p这个指针指向这个子节点,即p=son[0][0]=1;

2023-12-26 09:05:58 643 2

原创 基础数论一:判定质数和求约数相关

因数是成对出现的,如果d是x的因数,则x/d也是x的因数,又因为d

2023-12-25 16:37:12 517 3

原创 数据结构:KMP算法

前缀表也就是next数组要求的是最长相等前后缀的长度,例如a的最长相等前后缀为0,aaa得到最长相等前后缀为2,aaba的最长相等前后缀为1。

2023-12-25 09:27:06 2084 3

原创 栈的常见题型

的问题,所以我们想到用栈来解决问题,首先定义一个栈,然后就遇到了一个问题,我们遍历tokens时,怎么判断是不是数字呢,只有数字我们才能入栈,有三种情况:一位数,多位数,负数,对于负数我们可以计算这个字符的长度,如果长度大于1,就是数字;接下来我们定义一个栈stack,和头指针now指向head,把链表各个结点的值存入栈中,接着我们再定义一个ret作为反转后的链表的虚拟头结点,以及返回的结点,接着就是栈中的元素出栈,将链表的值进行更新,ret和head不断向右走,最后返回retHead->next;

2023-12-24 18:53:52 996 3

原创 数据结构:栈

栈是仅限在表尾进行插入和删除的线性表,栈又被称为后进先出的线性表。

2023-12-23 14:10:41 540 2

原创 基础算法(6):前缀和

首先我们求出所有前缀和,定义s来存储所有满足条件的数组元素之和,然后我们应该先枚举长度,因为有长度为1的奇数长度的子数组,也有长度为3的,我们要一个个进行枚举,然后我们再定义起点和终点,用来求区间的部分和,判断终点是否大于数组长度,如果大于就退出本次循环,又因为当l=0时,l-1=-1超出数组下标范围,所以当l=0时直接求和即可,如果都不满足,我们就进行迭代求和,需要注意的是,我们所求的和包括下标l的元素,所以应该是sum[r]-sum[l-1],而不是sum[r]-sum[l]。

2023-12-21 14:11:50 558 2

原创 链表常见题型(1)

这个题还是比较简单的,首先并不需要虚拟头结点,因为就算头结点的值和下一个结点的值相等,也会保留头结点,我们只需要遍历链表,如果cur的下一个结点的val值和cur的val值相等,我们就删除cur的下一个结点,需要注意的是循环条件是cur->next,当cur遍历到最后一个结点时,cur的下一个结点就不存在是NULL,此时应该退出循环,如果是cur则会继续进入循环造成NULL指针的解引用,会报错。我们要想删除链表的某个结点,需要利用上一个结点的next指针指向删除结点的下一个结点。

2023-12-20 12:16:16 1839 2

原创 数据结构:链表

int data;}ListNode;这就是一个结点的定义,我们把一个结点看成一个结构体,其中data是数据域,可以是任意类型,而struct ListNode* next定义了一个指向ListNode结构体的指针,这个指针的地址是后继结点,将指向下一个结点,这就是指针域,如下图所示下面看看具体怎么创建一个链表的结点。

2023-12-19 23:52:19 1095 4

原创 基础算法(5):滑动窗口

public:int check(char c)//每次遇到一个字符都需要进行判断,所以我们自己实现一个函数,避免重复代码return 1;return 0;int r=0;//窗口边界int cnt=0;//计数器int sum=0;//比较迭代的变量for(;r<n;r++)//开始遍历//向窗口内添加元素if(r>=k)//窗口长度大于给定值滑动直到长度等于k,减去左边元素,向右不断滑动//将sum和cnt的值进行比较,这里sum其实起到了比较作用,将cnt的值存储到sum中。

2023-12-19 09:04:40 598 4

原创 C++:类和对象(1)

属性:变量行为:函数/方法class 类名访问控制符:成员变量 //属性成员函数 //方法访问控制符有三种:public,private,protectedclass CAnimal //类名首字母一般大写public://属性int age;//方法void jiao(char* voice)//描述动物叫的行为,voice为叫的声音。

2023-12-18 22:54:32 767 2

原创 C++:函数重载

其实编译器在将我们得到程序编译完成后会将变量和函数变成一个一个的符号,存放这些符号的表格我们称之为符号表,我们可以对程序进行编译查看函数对应的符号。函数重载就是用同一个函数名定义的不同函数,当函数名和不同的参数搭配时函数的功能和含义不同。这几个函数虽然名字相同,但因为满足了上面三个条件的至少一个,所以是函数重载,不会冲突。我们看到在将函数转换成符号时,是根据函数名,形参类型进行转化的。c就代表char,i就是int,func就是func函数。

2023-12-17 21:14:54 182 1

原创 指针浅谈(五)

上一节我们刚讲过指针数组,指针数组是一个数组,里面存放的是地址(指针)。那什么是数组指针呢,数组指针是一个能够指向数组的指针变量,里面存放的是数组的地址。那怎么定义一个数组指针呢?这是什么意思呢?其实是p先和*结合,声明p是一个指针变量,然后指向一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

2023-12-17 12:08:09 237 1

原创 基础算法(4):排序(4)冒泡排序

i<n-1;j++)

2023-12-16 23:37:40 394 1

原创 C++:命名空间

namespace 名称//定义变量、函数、类型等等。

2023-12-15 19:29:12 120 2

原创 中文字符串逆序输出

接下来我查了资料才发现了我之前不知道的知识点,我们知道在字符编码方面,ASCII码为标准符号、数字、英文等进行了保留,取值范围是0~127,还有一部分作为拓展ASCII码128~255,当我们采用非ASCII编码时(汉字编码),一般用拓展ASCII码来进行,约定用128~255范围的连续2个进行汉字编码,因此,在处理字符串时,如果是有符号字符串,遇到小于0的字符,会结合后面紧跟的字符来组成一个汉字,如果是无符号的,则判断是否大于127。同时一个汉字占用两个字节,知道了以上的知识,才能写出正确的代码。

2023-12-15 14:58:12 413 2

原创 基础算法(3):排序(3)插入排序

问题规模仍然为n,最好情况是序列是升序,这样只需要比较n-1次,最坏情况是序列是降序,需要比较n(n-1)次,所以时间复杂度为O(n^2)(3)如果扫描到某个元素大于取出的新元素,将该元素移到下一个位置。(4)重复(3),直到找到已排序的元素小于或者等于新元素的位置。(2)取出下一个元素,在已经排序的序列中从后向前扫描。(1)从第一个元素出现,该元素认为已经被排好序。(5)将新元素插入到该位置后面。插入排序的工作原理是。(6)重复(2)-(5)

2023-12-15 13:01:59 541 2

原创 基础算法(2):排序(2):计数排序

计数排序是一个非基于比较的稳定的线性时间的排序算法,而选择排序是基于比较的,计数排序不用,它的实现依靠计数。很显然,问题规模为n,只进行了一次循环,没有进行比较,为n次,时间复杂度为O(n),这是很可观的。其实就是做了个映射处理,这个思想和哈希表很像,以后会讲到。

2023-12-14 20:53:01 168 2

原创 基础算法(1):排序(1):选择排序

今天对算法产生了兴趣,开始学习基础算法,比如排序,模拟,贪心,递推等内容,算法是很重要的,它是解决某个问题的特定方法,程序=数据结构+算法,所以对算法的学习是至关重要的,它可以提高程序效率,不同的算法也是有优劣的,如何进行评价,这也是我们需要知道的,我会在学习中穿插这种评价方法,下面让我们看看第一个基础算法排序中的选择排序。

2023-12-13 22:34:01 338 1

原创 指针浅谈(四)

在指针浅谈(三)中我们知道了数组名是什么,任何用指针访问数组,一维数组传参的本质是什么,这一次我们来学习二级指针,指针数组,以及如何用指针数组模拟二维数组。

2023-12-13 15:30:41 78 2

空空如也

空空如也

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

TA关注的人

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