自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 算法通关村——二分查找的应用

而不是舍入后的 4。所以这里 mid 的计算采用的是整除,当 left + right = 7 时,mid 的结果是 3,而不是 4。主要原因是在计算 mid 时使用的是整除 /,而不是普通的除法:mid = (left + right) / 2这里的 / 是整除运算符,会自动向下取整。综上,这种左右边界的初始化方式,既保证了区间的左闭右闭,也缩小了查找范围,排除了不可能的候选,优化了算法的效率。在C++中,std::vector的size()方法返回的是向量中元素的数量,索引是从0开始的。

2023-11-15 14:28:06 87

原创 ue——贪吃蛇笔记

根据你描述的这个贪吃蛇游戏的蓝图设置,为了让蛇头节点 bp_snake 可以连接并控制蛇身体节点 bp_snakebody,你需要在 bp_snake 中添加一个 NEXT BODY 变量,用来保存下一个蛇身体节点的引用。综上,根据贪吃蛇的实现逻辑,将 NEXT BODY 变量设置为 bp_snakebody 的类型,是连接和控制蛇身体节点最合理的选择。是蓝图编程中一个必学的技能点。根据你的描述,NEXT BODY变量存放的是蛇身体(bp_snakebody)节点的引用,不是头结点(bp_snake)。

2023-11-04 17:20:24 204

原创 第八关白银挑战——二叉树深度和高度问题

2. 当根节点的左右子树都为空时,根据minDepth的定义,应该返回1,表示根节点就是最小深度。但是这个代码返回了INT_MAX,是错误的。综上,这段代码通过递归比较每个子节点为根的子树的最大深度,求出其中的最大值,再加1就是以当前节点root为根的整棵树的最大深度。这句代码利用了pair的第二个元素访问语法que.front().second来获取队头元素的第二个值,也就是树节点的深度。综上,运用pair和emplace,可以将树的节点和深度信息同时高效管理,实现优雅的最小深度计算。

2023-10-25 11:06:21 79

原创 第七关白银——理解二叉树的遍历

所以这里需要用引用参数的方式,在主函数中定义 result,传引用给 preorder,preorder 再直接往 result 添加元素。preorder 函数并不能直接修改 preorderTraversal 中的 result。这样利用引用参数的机制,才能使递归函数直接往主函数的结果向量填充元素,实现两函数之间的耦合。主要原因是 preorderTraversal 这个函数无法直接修改传入的 vector。3. 所以需要主函数定义结果向量,传引用给递归函数,递归函数再直接修改。

2023-10-08 11:20:22 66 1

原创 vector容器学习

vector类似于数组 不过是动态的(相对于静态 也就是固定的) 不过它如果要变大是通过类似搬家的操作 不是像链表一样直接插入 而是创建一个新的地盘。因为发现二叉树算法中需要vector容器 所以在看黑马的vector来补习一下。随机访问的迭代器 (不大明白)迭代器则类似指针的概念。

2023-09-26 08:49:21 30 1

原创 十六白银——滑动窗口经典问题

因为直接获取字符会返回ASCII码,而我们需要换成数组下标,所以要减去 'a' 的ASCII码,使其对应的是a-z的下标区间。所以++cnt1[s1[i] - 'a']通过字符到ASCII码到数组下标的转换,巧妙地利用了数组来统计字符串中字符出现的频次。4. s1[i] - 'a' 对两个字符进行相减运算,由于字符有对应的ASCII码,所以相当于求两个ASCII码值的差。3. --cnt2[s2[i - n] - 'a'] 对应将离开窗口的字符s2[i-n]统计次数减1。

2023-09-23 15:13:13 30 1

原创 十七关白银——贪心高频问题

整体上这句代码的意思是:使用std::sort对intervals这个二维数组进行排序,排序的区间是整个数组,使用数组元素的第一个值进行升序排序,排序判断规则通过lambda表达式定义。std::sort函数的排序逻辑是根据比较函数的返回值来决定元素排序顺序的,这是通过std::sort函数的模板参数设计实现的。5. std::sort的最后一个参数是排序的判断函数,这里传入了lambda表达式,所以会按照这个规则进行排序。一个lambda表达式可以直接定义一个匿名函数,并将其作为参数传递给其他函数。

2023-09-22 12:30:41 26

原创 青铜挑战——贪心

这道题的意思是有两个数组 g 和 s,其中 g 表示每个孩子的胃口值(贪心值),s 表示每个饼干的大小。3. 从 g 数组末尾开始遍历每个孩子,如果当前孩子的胃口小于等于 index 指向的饼干大小,则可以满足该孩子,result++,同时 index--。所以这里设置 index = s.size() - 1 的目的是让 index 一开始就指向 s 数组中的最大饼干。这种倒序遍历的做法可以让一个饼干尽可能满足更多的孩子,同时也利用了排序让贪心思路更清晰。1. 首先对 g 和 s 数组分别排序。

2023-09-20 14:08:45 35 1

原创 十六关青铜挑战——滑动窗口基本思想

一种是通过直接更改left==right来更新 还有一种是直接计算好最终的count 如果小于直接清0。然后接下来也是通过数组的移动for(从i=k到n;i++)然后减掉一个 加入最新的数据。{然后在这里通过sum 把【i】个加总 也就是得到总和。首先我们需要确定一个窗口 也就是用for循环去整。这里的思想感觉并不是很难 但是主要是代码实现的问题。具体为for(int i=0;再通过一个寻找最大值的max函数 来找最大值。

2023-09-17 09:34:11 31 1

原创 十四关白银挑战——堆能高效解决的经典问题

至于排序:假设我需要从大到小排序 那么我每次都删除根节点(也就是最大的元素) 这样最终的效果就是从大到小排序了。举例 如果是找最大的用小堆 这样最后剩下的根元素恰好就是我们要找的元素(倒数第几大的元素)这样就避免了之后还要重新删除的麻烦。(本质上 这个删除的逻辑就是用了排序)官方题解中讲解的非常清楚了 但这是找最大元素 并且使用大堆根的情况。但其实 如果根据口诀 找最大用小 找最小用大有什么好处?

2023-09-16 20:29:33 28 1

原创 青铜挑战——字符串

单引号是代表字母的ascii码。在加上黑马的文档复习。

2023-09-12 21:48:46 24

原创 刷题模板之位运算——高频

使用 count+= 是因为什么?我愿称这个高赞回答为神!!!这段代码运用到了动态规划的思想来统计从 0 到 num 每个数的二进制表示中 1 的个数。关键思路是使用了备忘录 result 数组来存储已经计算过的结果,每个新结果都可以基于已经得到的旧结果计算产生,这样避免重复计算。具体分析:1. base case 是 result[0] = 0,0 的二进制表示没有 1。2. 对任意整数 i,如果是奇数,那么其 1 的个数是 i-1 的 1 个数再加 1。

2023-09-12 16:22:53 107

原创 算法通关村青铜——理解位运算的规则

与运算 :只有两个都是1才是1 其他都是0 可以用来判断 获取。很关键的一个点就是,他一定是在操作1的 而不是说去操作并不存在的0。首先 我们先了解基本的知识 也就是源码 反码 补码的概念。或运算: 只要满足一个1就是1 可以用来设置。源码就是基本的表示数。反码对于正数是不变的。

2023-09-07 16:43:17 63 1

原创 二叉树的深度优先经典问题——二叉树经典算法题

综上,这个代码缺少正确的递归逻辑,没有生成新节点,返回值和逻辑关系都有问题,无法正确实现两棵树的合并。所以这个自动创建新节点的代码,是mergeTrees核心逻辑的一部分,用于根据两个节点生成合并后的新节点。因为mergeTrees函数是要把两棵二叉树合并的,在合并的时候,对应位置的两个节点的值需要相加,生成一个新的节点。递归合并两个子树后,需要使用两个子树的节点值生成一个新的合并后的节点。它的作用是:创建一个新的树节点merged,这个节点的值是t1和t2两个节点值的和。- 如果p为假,q为真,则!

2023-09-03 19:17:14 265

原创 《算法通关村—如何使用中序和后序来恢复一颗二叉树》

中序遍历+前后遍历的任意一种 就可以确定根节点 所以可以成立。但是前中序列复原二叉树这个点 和之前所学的有些不一样。这个篇章与数据结构中所学的基本相同 理解上难度不大。

2023-09-03 15:05:56 237

原创 《算法通关村——透彻理解二分查找》——青铜挑战

因为:1. mid 不等于 0,说明没有到达数组最左端,不会数组越界2. nums[mid] 不等于 target,说明我们已经线性查找到了第一个不等于目标值的元素根据二分查找的定义,这个不等于目标值的元素的索引,就是目标值的左边界。以数组 [1,2,2,2,3] 和目标值 2 为例,如果想得到目标值左右边界,特别是右边界的索引,原始算法是无法处理的。如说给你有序数组 nums = [1,2,2,2,3],target 为 2,此算法返回的索引是 2,没错。

2023-09-03 14:54:01 300

原创 二叉树的层序遍历经典问题

首先 这需要vector容器和queue容器的知识 以上知识可以通过文档对照的去看然后 最花费时间的还是在找教程上面 最好优先对照leetcode上面的解析高赞看一遍 而不是在csdn搜索 这样效率比较高 leetcode上面讲的还是很不错的。

2023-08-29 12:47:03 275

原创 关于指针 引用 & *常见梳理

总的来说 分为声明时和调用时两种。总是忘记 所以总结一下。声明的* 创建一个指针。调用的* 返回该指针的值。调用的& 返回地址。

2023-08-21 14:38:30 23 1

原创 白银挑战——链表反转的拓展问题

首先附上leetcode虚拟头节点涉及换头的问题:假设我们有一个单链表,用于存储学生的信息,包括姓名和成绩。当我们需要对这个链表进行插入、删除或者其他操作时,通常需要考虑链表为空的情况和非空的情况。在没有虚拟头节点的情况下,如果链表为空,我们需要对头节点进行特殊处理。例如,当我们需要在空链表中插入一个新的节点时,我们需要单独处理头节点为空的情况,即创建一个新的节点并将其设为头节点。这样会使得代码逻辑变得复杂,需要额外的处理步骤。而当我们引入虚拟头节点时,可以避免对头节点的特殊处理。

2023-08-19 15:55:15 533

原创 白银挑战——链表高频面试算法

注意 如果直接定义两个数组 这样其实是没有用的 他们本质是两个完全不同的链表 并不能最后检测到一条上 所以正确的做法是通过先定义 然后每一个去连起来这样的方法。这样成立的理由是,不问前面是长还是短,那么后面的长度都是一样的。然后我们先让长的变得和短的一样,就让前面的长度也变得一样了。这种方法主要的思路就是通过先把长的并立到和短的一样长,然后两者共同走相同的步数。这样的话当长的便利到诺的时候短的就刚好遍历到所需的地方。的作用:将prev换成最新的节点 方便遍历。

2023-08-16 16:43:17 542 1

原创 算法通关村第三关--数组

如果能用for的情况我们用while 就需要手动更新迭代 还有初始化问题。第二个则是在删除的位置+1为i 从删除的位置一个一个的移动到尾部。第二个这么设计其实好理解 因为删除的地方是空缺的 从这边移动。其实就是一个占着茅坑的问题 别人占着茅坑 你就不能上。第一个是令j在最尾巴 然后一点一点从后面移动到插入位置。对比以上两个(一个是用来增加数组 一个是用来删除数组。初始化 退出条件 自动的迭代步数。一个小问题:怎么去理解for和while 的区别。思考以下for循环的逻辑。

2023-08-16 16:39:56 539 1

原创 算法通关村第二篇——反转链表

我的理解是 struct ListNode* prev = NULL等于新开了一个空链表 然后改变指针方向。注意:需要新建一个next结点用来储存cur->next 然后在一轮遍历后 通过cur=next重新遍历。构造虚拟节点的方法是创造一个ans 然后让原有的链表接入上去的一种做法。} 为什么struct ListNode* prev = NULL;总结思路:反转链表有两种思路 一种是构造虚拟结点,一种则是直接反转。

2023-07-20 17:32:36 1088

原创 《算法通关村第一关——链表青铜挑战笔记》

所以这行代码的作用是使用malloc在堆上动态分配一个结构体类型的内存空间,用于存储链表的头节点,并将其地址赋值给头指针head,后面可以通过这个头指针来访问和操作这个链表。在这里p和temp都代表指针变量,所以p = temp表示将temp指针的值赋值给p,使p也指向这个头节点,而不是通过p->next去更改p所指向的节点的next指针。这是结构体指针使用自己类型的主要原因。主要区别在于p = temp改变的是p自身的指针值,而p->next = temp改变的是p所指向节点的next指针值。

2023-07-19 12:50:05 1637 1

空空如也

空空如也

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

TA关注的人

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