- 博客(38)
- 收藏
- 关注
原创 代码随想录算法训练营第三十四天
这道题要求剩下石头最小的质量是多少,那么就把他们分成两半,两半的重量足够接近的时候,剩下石头最小的质量就越接近0,因此求出背包容量为sum/2的背包,最多能装多少重量的石头,然后拿这个值减去sum可得到另外一半的重量 两个相减即可得到最终的结果。zeroNumh和oneNum是当前装入的str的0的个数和1的个数类似于01背包的递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);这里的x,就是bagSize,也就是我们后面要求的背包容量。
2024-07-19 17:28:20
519
原创 代码随想录算法训练营第三十三天
将这个数组分割成两个子集,使得两个子集的元素和相等。那肯定是对半分,把vector里的元素求和取半就行了。求和用库函数也可以做,第三个参数是初始值。主要 学习了一下01背包的问题 二维dp数组和一维dp数组的处理 然后是。这道题用01背包来做确实比较难想。01背包的应用类题目。
2024-07-18 01:04:05
238
原创 代码随想录算法训练营第三十二天
这道题自己思考ac出来了,主要是这道题需要使用二维的dp数组进行规划,由于动归是递推的,所以从结果向前思考,因此到右下角的方法只能由右下角这个格子或者左边这个格子走过来,因此右下角这个格子的方法数应该等于上一个格子的方法数加上左边这个格子的方法数。值得注意的是只有一行的或者一列的每个格子都只有1种方法,还有就是多行多列的边界格子也是只有一种方法,这个也是要初始化的。然后初始化边界的时候在障碍物之前的都初始化为1,障碍物以及障碍物之后的都初始化为0;首先几个特殊情况 当障碍物在起点或者终点的话直接返回0;
2024-07-14 19:56:17
287
原创 代码随想录算法训练营第三十一天
这道题就是斐波那契的原理 只要明白的是 大于等于三阶的楼梯 只能由他的前两阶走上来,因为最多只能走2步,如第m阶只能由m-1阶和m-2阶走上来,又m-1阶的方法有i种,m-2阶的方法有j种,那么m阶的方法应该是 i + j 但是这里不是i + j * 2 的原因是因为 从m-2阶走一步到m-1阶的方法已经包括到了m-1阶的方法的方法里了,因此不用乘以2.我是按照 第一步是花费的,最后一步不花费,那么代码是这么写的,提交也可以通过。下面这种事默认第一步不需要消耗 但是最后一步需要消耗。
2024-07-14 00:58:26
352
原创 代码随想录算法训练营第三十天
代码随想录的方法比较难想 并且也有一些细节处理很重要 要不然想到这个方法也很难跑通 还有就是string 的库的调用。回了上面两个这道题并不难 这题主要就是发现重叠后更新一下当前元素的起始范围。这道题用暴力方法可以做但是会超时。
2024-07-11 11:09:34
195
原创 代码随想录算法训练营第二十九天
这道题有了上道题的基础就很容易做了 主要循环里判断是否当前元素的左边界是否小于上一个的右边界,然后右边界更新为当前元素和上一个元素最小的右边界值即可。因为元素的范围越小重叠的区间的概率就越小。这道题目我原本的想法是只要当前的气球半径范围在已有的箭头能够击穿的气球半径内就可以实现 但是 箭射出去的地方是一个值 而不是一个范围 因此有相同的重叠范围的许多气球并一定都有相同的值,因此这种方法不可取。之前的区间一定需要一个弓箭。因此重叠区域的气球一定要找右边界的最小值,这样才能确保所有气球都能同时被射爆。
2024-07-10 23:53:58
399
原创 代码随想录算法训练营第二十八天
局部最优可推出全局最优,找不出反例,那就试试贪心。整个插入过程如下:排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]
2024-06-18 00:03:28
684
原创 代码随想录算法训练营第二十七天
这道题目主要看0的问题 因为不能走到的问题只会是因为0限制了步数,我贪的办法(也就是局部极小值)是从后往前找有没有零的 如果有0就判断他前面的数的值是否大于他到这个零的距离如果大就没事反之则返回false;如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。从图中可以看出来,就是移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
2024-06-17 12:54:34
400
原创 代码随想录算法训练营第二十六天
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。这题确实自己想复杂了 自己在想如何删除元素 因为最后只要计数确实最简单的方法就是遇到峰值就++ 单调的就不++如果 -2 1 在一起,计算起点的时候,一定是从 1 开始计算,因为负数只会拉低总和,这就是贪心贪的地方!这里的局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),这个坡度就可以有两个局部峰值。区间的终止位置,其实就是如果 count 取到最大值了,及时记录下来了。
2024-06-14 22:39:45
335
原创 代码随想录算法训练营第二十五天
这道题目不能使用之前的used方法了 因为这道题目不能够排序 只能按照原有的数据排列方式进行查找子序列 因此只能使用unordered_set 来判断树层是否曾经使用过。可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。因此只要在全排列的题目的基础上加个 排序然后树层去重就可以解决了。那么排列问题其实也是一样的套路。
2024-06-11 23:33:47
520
原创 代码随想录算法训练营第二十四天
首先确定终止条件是 startIndex 是否已经遍历到了末尾 如果遍历到末尾 说明划分到了末尾 已经无法再继续划分了 这里还要再加一个条件才能保证划分的是合法的ip地址 那就是path路径里面的数量是4 因为划分时候的个数没有限制因此会出现单独一个数作为一个划分 那么就会把总体划分为十几个小组合放进path里这样的划分是不符合的。求排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合,排列问题我们后续的文章就会讲到的。有同学问了,什么时候for可以从0开始呢?
2024-06-10 23:40:20
266
原创 代码随想录算法训练营第二十三天
这道题目要考虑去重的部分 因为候选集合的元素里是有重复的元素 并且每个元素只能用一次所以对于候选集合无重复的用原来的方法不会有重复但是对于有重复的候选集合 用原来的方法就会有重复。可以使用双指针法,一个指针从前向后,一个指针从后向前,如果前后指针所指向的元素是相等的,就是回文字符串了。在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。
2024-06-09 20:24:13
1561
原创 代码随想录算法训练营第二十二天
然后是从每个数字对应的字母集合里取字母 注意不能在同一个字母集合里面取多个,这是不满足题意的 因此不能用前天的组合的那套方法 只能把每个数字对应的字母集合放入vector容器里 然后从每个索引里依次取一个字母来组成一个集合。然后单层逻辑一定要自己分析出树形图之后 写单层递归逻辑 其中横向 是用for循环控制的 用于从每一个字母集合里面取数字 然后递归是控制纵向的用于从不同的集合里取数字。首先得定义一个数组 把数字和字母做映射。
2024-06-07 23:38:30
279
原创 代码随想录算法训练营第二十一天
回溯本身是暴力的过程,可以看做是递归的循环,所以很多时候回溯是需要剪枝的,把某些不需要的或者不可能的回溯过程删除,达到提高回溯算法效率的目的。本题的剪枝其实就是缩小遍历的范围,如果剩余元素已经不够我们所需要的集合元素个数,就可以立刻停止搜索,只需要把i的遍历范围修改了即可。使用回溯三部曲就可以解决值得注意的是 使用startindex来控制取数的位置。只要修改循环条件就可以完成剪枝。
2024-06-05 23:44:58
146
原创 多传感器设备时间硬同步
每种电子设备都有各自的时钟,起始时间均不相同,而且因晶振质量的差异,频率也不同。由于时钟域未完全同步,所以未同步传感器的数据,时间戳只能定为计算平台接收到数据时的时间戳;这中间的误差∆t,通常在几ms到几十ms之间。各传感器成像的时间不一致,导致成像结果之间无法有效对齐,进而会导致各传感器检测到的障碍物位置发生偏差,自车速度越大,偏差越大。比如车速为120km/h,∆t = 0.1s,∆s = v ∗ ∆t = 3.33m,能达到3m左右的误差。所以多传感器系统需要尽量降低时间戳与真实成像时间之间的误差。
2024-06-05 15:12:16
1799
原创 代码随想录算法训练营第十九天
这道题目主要难在根据对于要删除的结点存在的位置进行分类删除 并且删除是在终止条件里的 因为找到了就可以进行删除了,没必要往下继续递归了 凡是二叉树的构造(删除添加的题目)递归函数都要TreeNode的返回值进行赋值 root->left = traversal(root->left,);因为是有序树,所以 如果 中间节点是 q 和 p 的公共祖先,那么中节点的数组 一定是在 [p, q]区间的。终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。
2024-06-04 21:42:43
779
原创 代码随想录算法训练营第二十天
值得注意的 是这个题目也是二叉搜索树以要找比自己节点的值都要从右子树开始找因此这道题目的遍历顺序是右中左 然后使用双指针的方法累加前一个节点的值就能够实现了。这道题想了一会才做出来了,因此二刷有必要回顾一下 主要思想就是不断对数组分为一半然后放入递归构建结点 并且 只要划半构建出来的二叉树一定是平衡的。如果root(当前节点)的元素大于high的数值,那么应该返回左结点。修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。代码随想录里的提供的代码是不新构建向量的方法。最终的代码倒是很简洁。
2024-06-03 16:37:03
279
原创 代码随想录算法训练营第十八天
如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。凡是提到二叉搜索树的都要记得先考虑中序遍历 因为中序遍历得到的数组是单调递增的数组 如果不用数组的话可以使用双指针法的中序遍历来解决问题。其实情况一 和 情况二 代码实现过程都是一样的,也可以说,实现情况一的逻辑,顺便包含了情况二。后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。这一点是很多录友容易忽略的,在下面的代码讲解中,可以再去体会。
2024-06-01 20:47:13
321
原创 代码随想录算法训练营第十七天
这道题目又很好的练习了一下 中序遍历 还有二叉搜索树是左边所有节点都要比中间节点小,右边所有节点都要比中间节点大 那么二叉搜索树的特征就是中序遍历的话得到的数组是单调增的因此可以遍历后判断数组是不是增的就能判断是不是二叉搜索树了。最大值所在的下标左区间 构造左子树 这里要判断构建的左区间vector数量> 0,因为要保证左区间至少有一个数值。构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。并且返回的也是中间节点。划分区间要注意的是区间不能为0 因为递归函数没有处理为空的情况。
2024-05-30 23:33:56
302
原创 代码随想录算法训练营第十六天
首先回忆一下如何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。遍历的路线,并不要遍历整棵树,只要找到符合的路径就可以返回了,所以递归函数需要返回值,可以用bool类型表示。
2024-05-29 21:49:52
727
原创 代码随想录算法训练营第十五天
当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int。因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。
2024-05-29 00:20:17
656
原创 代码随想录算法训练营第十四天
3. 确定单层递归的逻辑:就是写终止之前的递归程序的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。,所以本题中我们也通过后序求的根节点高度来求的二叉树最大深度。什么是叶子节点,左右孩子都为空的节点才是叶子节点。使用前序求的就是深度,使用后序求的是高度。尤其需要注意的是高度和深度的区别。遍历的顺序为后序(左右中),
2024-05-27 20:18:28
278
原创 代码随想录算法训练营第十三天
二叉树的右视图 需要后期再练一下 因为当时没有想到将每一层的最后元素放入result数组中就是最右边 因为层序遍历是从左往右的 那么最后一个肯定是最右边的 这种对于每层只有一个的很有效。这条题目首先确定遍历方式是用层序遍历还是深度遍历 然后翻转不只是翻转值而是翻转节点 这个可以通过swap函数实现 swap的两个参数都是可修改的左值即可。本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。,所以在递归遍历的过程中,也是要同时遍历两棵树。
2024-05-25 23:30:22
789
原创 代码随想录算法训练营第十二天
写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。前序遍历按照中左右的方式push_back进vector里 这个顺序也是子树的遍历顺序。在这里也就会重复调用自己来实现递归的过程。中序遍历还得看视频理解才能敲出来。
2024-05-23 14:47:55
260
原创 代码随想录算法训练营第十一天
单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。大家貌似对deque也有一些疑惑,C++中deque是stack和queue默认的底层实现容器(这个我们之前已经讲过啦),deque是可以两边扩展的,而且deque里元素并不是严格的连续分布的。此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。表示优先队列的底层容器类型,即优先队列内部使用的数据结构是一个。
2024-05-21 15:16:25
1832
原创 代码随想录算法训练营第十天
因此本体自己也手码出来了 主要的思路就是将每一个元素在放入栈之前判断他和栈顶元素是否相同 相同就弹出并且不放入 然后再把栈里的元素拿出来之后 反转一下就OK了。第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false。第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false。那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。
2024-05-19 17:10:05
131
原创 代码随想录算法训练营第九天
这道题比较简单主要是熟悉栈的一些基本操作 还有就是代码复用的问题确实很重要;这道题比较简单主要是熟悉队列的一些基本操作。
2024-05-18 15:50:22
179
原创 代码随想录算法训练营第七天
这道题自己想的复杂了 设置了很多条件 正如 卡哥所说习惯了i++,其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断这个2k以内是否需要有反转的区间,这里面要注意剩余字符若少于 k 个,则将剩余字符全部反转。该题要求空间复杂度为O(1),说明不能创建和字符长度有关的临时变量只能创建有限个的临时变量,然后最近受到双指针的影响比较大 于是使用双指针的方法解决了该题 并且。的逻辑是一样一样的,本题是移除空格,而 27.移除元素 就是移除元素。
2024-05-16 20:18:05
413
原创 代码随想录算法训练营第六天
因此可以通过将数组分为每两个一组(每两个一组的时间复杂度是2n^2 分为一个和3个的时间复杂度是n+n^3) 一组是第一个数组和第二个数组的和 因为不需要提交下标 因此只要保存二个数组的和进入map容器里就行了还有就是二个数组可能不同位置上的元素能相加产生相同的值 因此还需要记录每个值对应的次数这样就需要map容器来保存对应的key:数组之和-value:次数。很有难度 感觉面试出这种题的话 没有复习过的话很难完美的跑出来 复习的时候还得先看一边代码然后看视频复习一下。整体代码如下进行理解。
2024-05-15 20:50:20
310
原创 代码随想录算法训练营第五天
本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返set.end();所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,很暴力的解法是两层for循环查找,时间复杂度是O(n^2)。那么我们就应该想到使用哈希法了。
2024-05-14 21:07:47
226
原创 代码随想录算法训练营第四天
一上来的想法是将倒数第n个节点转换成从1开始的正数的第几个 因此首先得计算一下节点的个数 count然后判断倒数等于正数的第几个 如果是倒数第一个就是正数的第n个 因此转换成正数的公式是number = count - n + 1 但是这样执行while(n--) {cur = cur->next;判断停止的条件:要翻转的节点列表的个数如果为偶数个那么cur->next为空则停止,如果为奇数个那么cur->next->next为空则停止,空列表的话个数为0也符合偶数个的特点。题目还算简单暴力循环即可解决。
2024-05-13 23:08:26
352
2
原创 代码随想录算法训练营第三天
但觉得还是虚拟头结点很有用因此记录一下虚拟头结点的用法 虚拟头结点就是在原来的头结点前再新建一个节点,然后将虚拟头结点指向原来的头结点,最后返回的是dummyHead->next也就是原来的头结点,这样就可以避免要根据除头结点外第一个节点是否要删除而分类讨论的情况 使用虚拟头结点可以避免分类讨论的情况。这道题主要靠看了使用双指针和代码随想录里的动图就手码出来了 值得注意的是有关链表的题目都要注意空链表的处理,下面贴一下我自己写的代码。下面的是递归的写法留个印象 笔试前复习用免得忘记。
2024-05-13 15:05:52
227
原创 BootLoader
BootLoader 是系统加电后运行的第一段软件代码。回忆一下 PC 的体系结构我们可以知道,PC 机中的引导加载程序由 BIOS(其本质就是一段固件程序)和位于硬盘 MBR 中的引导程序一起组成。BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的引导程序读到系统的 RAM 中,然后将控制权交给引导程序。引导程序的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。而在嵌入式系统中,通常并没有像 BIOS 那样的固件程序,因此整个系统的加载启动任
2021-06-25 09:46:20
108
原创 xbyte
使用keil 开发单片机程序时,在absacc.h 这个头文件中,有XBYTE这样一个宏。它的定义是 #define XBYTE ((unsignedchar volatile xdata *) 0)可以使用XBYTE去访问外部的RAM,也可以用XBYTE去访问扩展的I/0设备注意:这里是利用的英特尔总线进行访问的,那么就会有时序的问题,在C语言中,这些都帮你做完了,所以无需考虑3、关于I/O的控制如下,低字节表示的是P0端口,高字节表示的是P2端口。P2端口通常作为控制端口,而P0通常作为数据端口eg:
2021-06-14 16:38:34
392
原创 l do
LDO是用MOS或者三极管的可变电阻区和线性区对采样电压进行负反馈调节的,由于是调节,所以也会产生震荡,但是这个震荡幅度比DCDC不同型号之间差别巨大,现在大部分DCDC的真当幅度都比LDO小,但是DCDC是开关的,输出电压谐波频率高,需要注意EMC/EMI设计。至于性能。毫无疑问现在的DCDC还是主流,体积小,重量轻,输出精度高,可靠性高,效率高,发热量低,输出电流不随输入电流变化,为啥不用呢?卫星上的模拟供电都是DCDC的,也没见NASA用LDO给卫星上供±15V啊https://mp.weixi
2021-06-13 16:35:50
229
原创 画了这么长时间的pcb,你还不知道为什么晶振要紧靠ic?
画了这么长时间的pcb,你还不知道为什么晶振要紧靠ic?## 标题晶振是通过电激励来产生固定频率的机械振动,而振动又会产生电流反馈给电路,电路接到反馈 后进行信号放大,再次用放大的电信号来激励晶振机械振动,晶振再将振动产生的电流反馈给电路,如此这般。当电路中的激励电信号和晶振的标称频率相同时,电 路就能输出信号强大,频率稳定的正弦波。整形电路再将正弦波变成方波送到数字电路中供其使用。问题在于晶振的输出能力有限,它仅仅输出以毫瓦为单位的电能量。在 IC(集成电路) 内部,通过放大器将这个信号放大几百倍甚至
2021-06-10 19:51:11
215
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人