- 博客(22)
- 收藏
- 关注
原创 6.3||二叉树的遍历
先让指针到树的最底层,然后放入节点,接下来再往左肯定是空的,那么此时应该进行下面的内容。现在的指针指的是空节点,那么我们应该让指针指向栈顶,然后把栈顶元素压入结果数组中,由于这个就是最左边的节点然后弹出,并给到它的右节点吗,如果右节点不为空那么就进行上一步否则就会去除上一个节点继续进行判断,中序就是这样,注意结构就是在while循环过程中 ,用新节点记录当前栈的栈顶,然后就让弹出把值放进结果数组里,然后就是把右节点和左节点压入栈,后压入左节点,那么先出来的就会使左节点,刚好符合前序遍历的顺序。
2024-04-01 10:51:11
369
原创 额哈哈哈哈哈
https://zhuanlan.zhihu.com/p/451972134?utm_source=wechat_session&utm_medium=social&s_r=0
2024-03-27 16:44:20
130
原创 6.2||二叉树的递归遍历
所以重点写一下前序,首先确定函数的参数,先想想遍历的时候需要什么,首先肯定要存储当前节点的值那就肯定要建立一个容器,这是第一个参数,同时注意由于是递归这个值是会被修改的所以我们要加上&,从而使得无需创建副本 就能直接修改参数值;而加上了这个符号,那么就可以直接在传递的过程中来修改参数,然后就是书写逻辑了。前序遍历,中左右,先是中间节点,然后左节点然后右节点,指针过去的过程中,先存储中间节点的值,然后去找左节点,然后存储左节点的值,然后继续往左找,直到终止了再去找右节点的值,按照这个逻辑一直递归下去,
2024-03-26 10:18:12
154
原创 3.5||四数相加
这边前两个数组搞完了,然后我们来找目标值和前两个数组key/的差值,其实这个就和上面一道题很像了,把后两个数组当成一个数组就行了,然后是第二个循环,由于要返回的是最终符合的次数,所以这里还需要定义一个值来记录次数。内容和上面差不多,主要就是循环的方式,范围循环只有两个参数for(1:2),前面是选哟我们定义的用来遍历的指标,后面是我们所遍历的对象。这里在给一个范围循环的,以后能用到:自动遍历一个容器(如数组、容器、字符串等)中的每个元素。两个题的解题思路基本一致,里面用到的方法也是差不多的,
2024-03-24 17:55:41
238
1
原创 3.4||两数之和
由于要返回key值,每个key值有对应的value,所以很明显这里的key就是我们的数组元素,map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)。在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。类中提供的一个成员函数,用于计算指定键在容器中的出现次数。先进行映射的初始化,
2024-03-24 17:42:12
294
1
原创 3.3||快乐数
用这个比较方便不需要考虑顺序,而且比较高效。因为前面运算过了求和函数,所以我们只需要一直循环求和函数即可,每当出现了一样的数也就是find的迭代器找到了那就证明这个数不是快乐数就直接返回false即可,注意这个逻辑,一旦有1说明循环该结束了,一旦还在循环每次出现的数都要记录在哈希表里,然后继续循环找是否会出现重复的值,重复了那就证明出错了。判断sum是否重复出现就可以使用unordered_set。每个数的个位就是n%10,然后每次运算之后在除以10就可以得到去掉个位数的数。
2024-03-22 23:05:25
136
1
原创 3.2||两个数组的交集
这里有三种结构,注意其中的区别,std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。这个代码本身没什么好讲的,那就拓展一下,关于迭代器的知识,迭代器还有其他的方法如begin和end,表示指向第一个元素和最后一个元素的下一个元素的迭代器(尾后迭代器),如果容器为空,则。,可以确定集合中是否有查找的元素。
2024-03-20 22:43:34
286
1
原创 3.1||哈希表开篇——有效的字母异位词
题目没什么难点,直接暴力解法双循环可以做出来,这里就用以数组为基础的哈希表试试。只定义一个也可以,那就少分配点空间。这样循环的话,刚好每个字母的出现次数就对应每个字母了、然后就是判断这两个数组是否相等,返回题设即可。哦对,如果两个字符串大小不一致的话直接反措即可。数组和链表结束,开始哈希表。哈希表的主要作用就是判断一个元素是否出现在集合里,然后哈希表是根据关键码的值而直接进行访问的数据结构。哈希表主要有三种结构,分别是数组,set和map。
2024-03-19 21:02:32
229
1
原创 2.4||有序数组的平方
用双指针的话,先考虑这个数组本身,它是有序排列的,平方了之后,我们可以想想数组的值是怎样的?它的最小值不一定在两边,但是最大值肯定是在两边的,只是左边或者右边的问题。那就两个指针同时往中间移动即可,两边的最先开始比较,比较大小之后最大值直接就确定了,然后用新指针去指代新数组的最大下标即可,然后刚刚判断出来的那个元素就可以向下一位移动了。很明显这个题也可以暴力解法循环,就不这样写了,当然也可以偷懒用库函数,先平方后排序也很简单。
2024-03-14 12:14:34
506
1
原创 2.3||删除数组元素
但是注意细节要时刻记录数组的长度毕竟最后要返回数组长度的,还有点就是我们在定义函数的时候,参数列表里如果有数组或者其他参数的话,加和不加&是由区别的,加了即代表引用,那么数组发生变化可以直接被看见,也就是说在函数里是可以修改数组的。注意循环里的条件,由于涉及到加减操作,所以判读里肯定要包含,然后就是左边找等于val,所以我们判断不等于val的时候才需要指针向前移动,分别占据左右端点,然后对于左边的指针它是用来寻找等于val的元素的,右边的指针是用来寻找右边不等于Val元素的,
2024-03-14 12:05:01
370
1
原创 1.2||二分查找
如果是左闭右开的话那么就是while(low < high),注意这个时候是无法取到high的,if(nums[middle] > target) high 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以high更新为middle,即:下一个查询区间不会去比较nums[middle]。然后用中点值和目标值比较,如果中点值大于目标值,那就说明我们的右端点需要往下移动了,反之就是左端点需要往上移动,所以这个逻辑不是很复杂。
2024-03-14 11:09:47
325
1
原创 2.8||环形链表
这是开始走圈的过程,我们了解到这样走的话,如果有圈的话,两个指针肯定是会再次相遇的,那么当两者相遇的时候我们的循环就可以停止了然后就是找入口的操作,同时注意这个相遇节点还有用处,在计算最终的入口距离的时候。那么如果n不等于1,那就说明着要走可能很多圈才能遇到,但是其实的最终效果是一样的,因为前面我们已经知道了它们的相遇节点,不管这个n等于多少,我们只要让一个从头开始,一个从相遇节点开始出发,由于。这个公式说明什么呢?,n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。
2024-03-11 10:38:16
372
原创 2.7||链表相交问题
首先先求出两链表的长度,用遍历即可,然后求出两链表的长度差值,这样知道了差值之后我们就可以让长的那个链表的指针先走到相应的位置,然后给另一个链表也设置一个指针吗,两个指针这个时候就可以同时出发了 ,结束条件是是什么呢?就是两个指针相等了。这道题用双指针会变得很简单,同时我们需要想想两个链表相交了,那是不是就说明相交处后面的部分是一样的,那么我们其实可以开始就想办法让他们后面对齐,这样就能更方便的进行后续的判断了。肯定不是数值相等,势必意味着两链表相交处指针是一样的,那就判断指针即可。
2024-03-10 10:26:26
329
1
原创 2.6||删除链表中的倒数第n个节点
其实举个例子就行,假如五个节点,1,2,3,4,5,要删除倒数第二个节点,那么i-n就等于3,我们发现刚好是要删除节点的前一个节点所以成立。这个也很巧妙,但是其实也是上一个的变形,快指针走了n步,那就意味着还剩下i-n步,再给慢指针走,而上一个方法是用了一个循环来找出这个i,这个方法把两个指针放到了一个循环里降低了时间复杂度。好像也不能完全叫双循环,我这个具体点叫两个循环,就是用第一个循环得出链表的长度,用第二个循环找到要删除节点的前一个节点,这样的话就能实现删除操作,给你一个链表,删除链表的倒数第。
2024-03-08 11:01:32
354
1
原创 2.5||两两交换链表中的节点
然后就看在怎么设置了,既然两两一改动,那就势必涉及到三个节点的问题,虚拟头节点,当前节点,以及第三个节点。然后就是循环过程,移动指针指向虚拟头节点,然后temp指针指向头节点,然后temp1指针指向第三个节点,注意这里为什么是第三个节点?给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。就是两两交换,然后他说节点交换,那就是变动指针,其实和上个反转链表很像,但是这里稍微细节多一点点,因为只能两个一反转。
2024-03-07 21:48:21
352
1
原创 2.4||反转链表
说实话,这道题挺难想的,一开始很难想到用递归法来解决问题,先考虑用传统方法来看,简单来说就是一个一个改变链表元素的指针,从而实现反转,这里就需要设置两个指针了,一个指针往前走,另一个紧随其后,并将原来向前的指针向后连着。分析原因,首先temp记录的是当前cur也就是头节点的位置,后续头节点指向了pre节点,然后pre向前移,到了最后一步,这里写的是把temp的下一位指向cur,可是问题在于temp里面存的是头节点的地址,它里面并不包含它下一位的地址,这里我改天出个简单的测试例子看看就行了。
2024-03-06 23:28:16
653
1
原创 2.3||设计链表
第二个就是插入一个元素到头节点之前,这个也比较简单,我们不是定义了一个虚拟头节点嘛,直接把虚拟头节点的下个指针指向我们新的那个节点,然后新节点的指针指向原先的头节点即可,要注意的就是链表长度记得更改否则后面会编译失误。第一个是获取链表值,它说了下标无效那我们首先写出链表无效的情况,这里无非就是下标越界了,要不就是下限小于0要么就是上线大于数组减一,然后在加一个while循环,得到了index的那个下标,返回cur->next-val即可。这篇还是不错的,毕竟啥操作都有,注意下细节问题,比如链表长度。
2024-03-06 23:00:13
324
1
原创 2.2 || 移除链表元素
我这里多写了一行代码,注意区别,其实也就是删除头节点和其他节点的区别,对于头节点而言,我们直接把他的下一位作为头指针即可,也就是头指针移动到下一位的意思。链表的含义不在过多赘述,我在开头提一下,对于链表的操作而言实际上是指针的操作,明白这个就简单很多了,还有就是一个头指针是必须的但是头节点不是必须的,因为假设没有头指针那么根本无法开始下一步操作,示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]题意:删除链表中等于给定值 val 的所有节点。
2024-03-04 22:41:52
377
原创 算法数组篇 | 5. 最小子数组补充
所以循环需要的是设置终点。这里是复合代码,但是也不难理解,当一个窗口满足之后,我们需要移动这个窗口的起点,起点节点是i,所以需要i++,但是i++了之后窗口值肯定也需要发生变化,这个值也需要向前移,之前的那个值就需要删除,所以需要讲那个值从sum里减去。上一版的方法用了暴力解法双循环,这方法虽然简单但是很容易超时,双循环的时间复杂度太高了,那么我们需要考虑降低时间复杂度,能不能只用一个循环来解。循环内容基本一样,只是一个循环用来控制窗口的终点,那么到底怎样才能控制起点呢?那本次就来介绍滑动窗口法。
2024-03-01 11:15:08
363
原创 算法数组篇 | 5. 最小子数组
条件成立则赋值值1否则是值2..这里的数组序列长度比较就可以运用到这个运算符,不断地让长度值length和result比较直到找到最小值然后结束循环,同时注意结束循环时的break是跳出最内层的循环并不是所有循环。两个循环,也可由理解为两个指针,需要注意的是sum的求和值应该在两个循环之间,由于每次j移动都需要求和因此sum的值都要发生变化。然后是长度值的定义,不是简单的j+1,这是因为i不是固定的,i和j都会变化,因此长度是j-i+1。暴力解法即采用双循环找到需要的数组然后在不断往前挪比较最小的序列。
2024-03-01 11:04:13
543
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人