- 博客(57)
- 收藏
- 关注
原创 C++易错点 && LeetCode易错题[持续更新]
C++易错点s.size()是无符号整型,变为负数后就变成很大的数,因此需要用int size = s.size()保存该数。
2023-04-12 09:01:11
81
原创 牛客面试top100难题
BM20 数组中的逆序对题目链接:BM20 数组中的逆序对思路:分治思想,本质是归并排序或者快排。代码://归并排序//首先将数组进行拆分,每次平均分成两组(类似二叉树),直到单独一个元素//然后对每个元素进行归并,归并的过程中,两个子数组都是有序的(类似合并有序数组)class Solution {public://取模就是取余数 void merge(vector<int>& data, vector<int>& copy,int lef
2023-06-14 12:58:31
347
原创 随想录训练营52/60 | LC 84.柱状图中最大的矩形
思路和接雨水一样,但是要找到每个柱子左右两边比它矮的柱子。然后以该柱子的高度为基准统计最大矩形。注意:要在数组的首尾加上0元素,防止一直在循环中没有结果。
2023-06-04 22:48:05
315
原创 随想录训练营51/60 | LC 503.下一个更大元素II;LC 42. 接雨水
找到某元素右边第一个更大元素使用的单调递增栈,为什么叫递增栈,是因为栈取元素时只能从栈顶到栈底,然后栈顶到栈底元素值越来越大的就是递增栈。1.找到每个柱子(栈顶的柱子)的左右两边距离最近的比它高的柱子,首先右边比它高的柱子就是遍历的柱子,左边比它高的柱子为栈顶下面的柱子;2.统计两个柱子之间的距离以及两边柱子与栈顶柱子的高度差,来计算雨水量。:与上一章节的题目不同之处为循环数组,因此遍历两边数组即可。在用单调栈模拟接雨水的过程中模拟的是。
2023-06-04 22:08:43
304
原创 随想录训练营50/60 | LC 739. 每日温度;LC 496.下一个更大元素 I
本质上还是找nums2中每个元素的下一个更大元素,不过只保存nums1中元素,并且保存的顺序也按nums1来。那么可以给nums1设定map,每次nums2找到下一个更大元素的时候,就看nums1是否有该元素,若有该元素就保存结果。:不是按着顺序去得到每天之后的更高温度,而是通过栈将未能得到更高温度的天保存下来,然后向后遍历,每次遍历的元素要和栈顶元素比较若遍历的元素温度高就移除栈顶元素,并且将栈顶元素对应的结果保存下来,直到栈顶元素的值比遍历的值大,再将遍历的值放入栈中。
2023-06-02 09:31:52
253
原创 随想录训练营49/60 | LC 647. 回文子串;LC 516.最长回文子序列
【代码】随想录训练营49/60 | LC 647. 回文子串;LC 516.最长回文子序列。
2023-05-31 22:37:46
136
原创 随想录训练营48/60 | LC 583. 两个字符串的删除操作;LC 72. 编辑距离
一遍遍历一遍更改字符串,当某位置的字母相同时, 就不做更改;若字母不同,那么就根据之前的结果进行更改,其中dp[i-1][j]表示从之前的删除一个字母得到现在的所用的步骤,dp[i][j-1]表示从之前的增加一个字母得到现在的所用的步骤,dp[i-1][j-1]表示从之前的更改一个字母得到现在的所用的步骤。:找到两个字符串的公共子序列,然后用两个字符串的长度减去2倍的公共子序列的长度。这个不好想到,需要动手推导,而且初始化也与之前不同。
2023-05-30 11:16:49
123
原创 随想录训练营46/60 | LC 1143.最长公共子序列;LC 1035.不相交的线;LC 53. 最大子序和 动态规划
当遍历的两个子数组某个位置值相同时,就将对角线上一个值加+1;不同点是,当值不同时,之前是不用管直接是0,现在是进行赋值。取之前更新的行列的最大值,该值表示,在此之前有最大长度为该值的最长公共子序列。:对于dp数组的每个值进行更新,更新规则是,当上一个的dp值加上该值比该值大,那就继续加,若小的话,就更新为当前值。当前面累加的是正数,然后遍历到一个负数,也会累加,知道累加的负数才重新累加。
2023-05-28 22:16:16
103
原创 随想录训练营45/60 | LC 300.最长递增子序列;LC 674. 最长连续递增序列 ;LC 718. 最长重复子数组
用二维dp数组,横纵分别表示两个数组。dp数组中的值表示最长公共子数组的长度,更新是判断两个数组该位置的值是否相等,若相同就更新,更新规则是对[i-1][j-1]的位置的值加一(i,j位置的值相同,那么就看他上一个位置的值是否相同)。所以需要对第一行第一列的值进行初始化。:用dp数组记录从开始到每个值的最长递增子序列的长度。将dp数组所有值初始化为1,更新第i个值时用前面所有的值对i进行更新,哪个大要哪个。:dp数组的更新与上一题相比更简单。
2023-05-26 11:24:31
250
原创 随想录训练营44/60 | LC 309.最佳买卖股票时机含冷冻期;LC 714.买卖股票的最佳时机含手续费;股票交易总结
只交易一次的可以交易无数次的最多交易两次的最多交易k次的买卖无数次,但卖后有冷冻期的买卖无数次,但卖后有手续费的。
2023-05-25 13:11:59
179
原创 随想录训练营43/60 | LC 123.买卖股票的最佳时机III;LC 188.买卖股票的最佳时机IV
本题思路和上一题一摸一样,只不过交易k次,为了每次更新方便,就再加一列表示什么都不操作。:不好想到用怎样的dp数组进行保存,而且更新的时候也和之前的不同。
2023-05-24 10:59:37
161
原创 随想录训练营42/60 | LC 121. 买卖股票的最佳时机;LC 122.买卖股票的最佳时机II
第i天持有股票时,有两种选择:用上一天的持有股票,或者不管之前的持有今天的;第i天不持有股票时,也有两种选择:用上一天不持有股票带来的收益(可能为0),或者今天卖出(今天的价格+上一天的持有,因为持有是负值,所以是加法)得到的收益。之前只能一次交易时,只能看-prices[i]与之前的差距,现在可以多次交易可以通过看之前挣得钱与本次持有的差,若挣钱多,就可以再次买入。贪心算法:将只统计遍历过的最小值,并且再每次迭代时更新结果,若有更大的结果就进行更新,否则保持原样。
2023-05-23 22:59:09
183
原创 随想录训练营41/60 | LC 198.打家劫舍;LC 213.打家劫舍II ;LC 337.打家劫舍III
本题思路:**遍历二叉树,二叉树的节点有两个值,分别为使用该节点值时的最大值,不使用该节点时的最大值;为什么每个节点要用到两个值?**因为可以用一个值的,但是一个值要对节点的孩子和孙子分别进行判断;若每个节点中有两个值,那么就只需看该节点的孩子节点即可。:若投了开始那家,就不能偷最后一家,若偷了最后一家,就不能偷开始那家。:偷第i家,通过第i-1和第i-2家得到,哪个大选择哪个。对dp[0]和dp[1]进行初始化。:自己的思路为层次遍历二叉树,将每层的金额之和保存,然后像上面问题一样去偷。
2023-05-22 23:53:09
185
原创 随想录训练营40/60 | LC 139.单词拆分;多重背包
多重背包就是规定了每个物品的个数,介于01背包和完全背包之间。可以将其作为01背包进行求解。
2023-05-22 22:24:29
149
原创 随想录训练营39/60 | LC 70. 爬楼梯 (进阶);LC 322. 零钱兑换 ;LC 279.完全平方数
之前本题是按着斐波那契数列的思路来求解的,和上一章节中的组合数联系,可看到这两道题的本质是相同的,总阶数就是我们的target,每步走1或者2步就是数组中的值。基于dp,我们还可以求解m步到楼梯顶的方式。:完全背包,dp数组内的值dp[i][j]表示得到j用第0-i个值至少用几个数,因此它的更新公式是求最小值,所以需要将其初始化为最大值,而dp数组的第0个值初始化为0,因为后面需要对其加1.:思路与上一题相同,但是需要自己创建nums数组。
2023-05-22 11:32:17
173
原创 随想录训练营38/60 | 完全背包;LC 518. 零钱兑换 II;LC 377. 组合总和 Ⅳ
完全背包和01背包的区别就是,完全背包能将某个物品添加无数次。在二维dp数组迭代更新中体现为:01背包dp数组由左上面的数组更新而成;完全背包do数组由包括本行在内的左边的数组更新而成。在一维dp数组迭代更新中体现为:01背包是从后向前遍历;完全背包是从前向后遍历。
2023-05-22 09:49:39
546
原创 随想录训练营37/60 | LC 1049. 最后一块石头的重量 II;LC 494. 目标和;LC 474.一和零
题目链接LC 1049. 最后一块石头的重量 II思路:和分割等和子集很像,都是将数组分成两组,让这两组数之和的差尽可能的小。代码public ://本质就是将石头分成两组,两组互相抵消,得到最小的重量 //与上一章节的分割等子集类似,都是将数组分成尽可能相似的两组 int lastStoneWeightII(vector < int > & stones) {sum += a;
2023-05-19 22:31:31
177
原创 随想录训练营36/60 | 01背包理论基础;LC 416. 分割等和子集
给定物品的重量、价值和背包的最大容量,问如何取物品使得背包中的总价值达到最大?
2023-05-18 11:08:55
271
原创 随想录训练营35/60 | LC 343. 整数拆分;LC 96.不同的二叉搜索树
从头节点出发,头节点的左右子树和之前的树的总数有关。:从开始往后推看前面与后面的联系。
2023-05-18 09:07:07
236
原创 随想录训练营34/60 | LC 62.不同路径;LC 63. 不同路径 II
之前的DP数组都是一维的;也是先举一个小例子,发现第一行和第一列都是1;然后第二行第二列开始为前一个数和上一个数之和,后面都是这样,因此遍历除第一行和第一列的数组就好。:按照上题思路,然后将障碍物的位置dp设置为0。注意初始化的时候,若遇到障碍物,则后面的不用初始化为1,直接break。
2023-05-16 22:47:13
383
原创 随想录训练营33/60 | 理论基础;LC 509. 斐波那契数;LC 70. 爬楼梯;LC 746. 使用最小花费爬楼梯
有一点点的贪心,然后再加上动态规划,到0或1位置时无需花费体力,但是到2时要花费从0到2或者从1到2的体力,两者进行比较取小值;:从1开始一步一步模拟发现有规律可循。:按着给的公式写就行。
2023-05-16 22:21:51
133
原创 随想录训练营32/60 | LC 738.单调递增的数字;LC 968.监控二叉树
若左右子节点都是被覆盖状态,则该节点返回未被覆盖状态(0),也就是上述状况,但不一定要安装摄像头;:从叶子节点往上进行判断,因此用后序遍历;空节点,则返回1,表示被覆盖状态,因为是为了保证叶子节点是未被覆盖状态(0);若左右子节点至少有1个节点未被覆盖,则该节点需要安装一个摄像头,且返回状态2;定义为0时表示节点未被覆盖;为1时表示节点被覆盖;为2时表示节点上有摄像头。若左右子节点至少有1个节点安装摄像头,则该节点无需安装摄像头,返回状态1;若头节点未被覆盖,则将头节点安装一个摄像头。
2023-05-16 21:41:50
167
原创 随想录训练营31/60 | LC 435. 无重叠区间;LC 763.划分字母区间;LC 56. 合并区间
统计最大的非重叠区间的个数,再让总区间个数减去非重叠区间个数就最少的是删除区间的个数。**像上一篇文章讲的类似,对区间进行排序,然后遍历区间,若区间去上一区间有重叠的,就更新重叠区间边界;若区间去上一区间没有重叠的,就增加非重叠区间个数。划分时要注意,第一次划分要让下标减去-1才可以得到划分的个数,后面只需让下标减去上次划分得到的下标即可。:将区间按照起始位置进行排序,然后依次插入到result中,若插入的区间和result最后的区间有重叠就将result最后一个区间进行扩充;
2023-05-16 20:31:16
200
原创 随想录训练营30/60 | LC 860.柠檬水找零;LC 406.根据身高重建队列;LC 452. 用最少数量的箭引爆气球
LC 860.柠檬水找零题目链接:LC 860.柠檬水找零思路:因为是按着顾客来的顺序进行找零,所以比较简单;每次找零时要先判断有没有可以找的大钱,然后再找小钱。代码:class Solution {public: bool lemonadeChange(vector<int>& bills) { vector<int> nums(2,0);//vector的大小为2,每个值都为0,从0到1分别表示的手头5美元、10的钞票个数
2023-05-16 11:41:29
167
原创 随想录训练营29/60 | LC 1005.K次取反后最大化的数组和;LC 134. 加油站;LC 135. 分发糖果
题目链接:LC 1005.K次取反后最大化的数组和思路:我的思路:对nums进行排序,当最小值为负数时就把负数转为正数,若最小值为正数,就看k是奇数还是偶数,偶数就不变,奇数就把最小的正数转换为负数,然后计算总和。另一种思路:将nums通过绝对值由大到小进行排序,遍历nums,当遍历值为负数,且K大于0时,就将遍历的数取相反数并且K–;当遍历结束后K仍有值且为奇数,那么就将最小的正数取相反数。如何自定义自己的sort函数?代码:LC 134. 加油站题目链接:LC 134. 加油站思路:从0开
2023-05-15 21:39:50
82
原创 随想录训练营28/60 | LC 122.买卖股票的最佳时机II ;LC 55. 跳跃游戏;LC 45.跳跃游戏II
如果我知道未来会发生什么事情,那么就不用暴力求解可以通过贪心来计算。
2023-05-11 22:22:25
187
原创 随想录训练营27/60 | 理论基础 ;LC 455.分发饼干;LC 376. 摆动序列;LC 53. 最大子序和
贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。不用花心思去研究其规律, 没有思路就立刻看题解。基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。学完贪心之后再去看动态规划,就会了解贪心和动规的区别。定义:选择每一阶段的局部最优,从而达到全局最优。什么时候用贪心?:手动模拟感觉可以通过局部最优推出整体最优就可以试一试。步骤:题目链接:LC 455.分发饼干思路:大饼干给小朋友亏了,但是若大饼干给胃口大的朋友也不会满足,所以,要将饼干从大到小排
2023-05-11 14:27:05
96
原创 随想录训练营26/60 | LC 332.重新安排行程;LC 51. N皇后;LC 37. 解数独
和n皇后差不多,每次写下数的时候要判断:该数在这行是否已经出现过,在这列是否已经出现过,在这九宫格是否已经出现过,若没有就填入。二叉树的层内为每个空位置可以取得数的范围(1-9),二叉树的深度为空位置的个数。:从固定机场出发,搜索从其开始的航班,然后按顺序记录航班的行程。已经去过的地方不能再去,所有的机票都要使用但不能重复使用,只有当这样,才可以保存行程。小的满足的话,就直接返回小的。:重点是构造一个二维数据结构(棋盘),当一个位置被占用后,该位置的行、列、两条斜线都同时被占用。
2023-05-10 10:42:29
179
原创 随想录训练营25/60 | LC 491.递增子序列;LC 46.全排列;LC 47.全排列 II
子序列是递增的,每个子序列至少有两个元素,这两个元素可以是相同的,但不能在全集上重复取,结果也不能有重复(用集合set来保证);递增通过准备加入的元素需大于path的最后元素来保证。:不传id了,直接改vector,若将元素加入path中,则需要从nums中删除加入的元素,回溯的时候同样需要重新加回到原位置。:需要在上题基础上增加去重操作,同样是同一层中不能有相同值取出。
2023-05-09 19:22:38
154
原创 随想录训练营24/60 | LC 93.复原IP地址;LC 78.子集;LC 90.子集II
注意去重,当一个元素作为首元素进行组合后,如果后面一个数与该数相同,那么就直接跳过后面的数,因为会有重复的情况。:给定一个字符串,返回有效的IP。其中无效的IP有:大于255的数;:穷举所有可能性,但是不能重复;每次取子集都向后退一位。空集和全集也包括在内。
2023-05-08 22:01:20
181
原创 随想录训练营23/60 | LC 39. 组合总和;LC 40.组合总和II;LC 131.分割回文串
递归法,每次将集合中的一个元素放到临时vector中,判断vector中的值是否满足要求,若满足要求就保存vector,并且返回;若不满足要求就继续递归,但递归的集合中没有刚进入vector的元素。:将字符串分割成子串,每个子串满足回文子串的要求。先取第一个字符判断是不是回文子串,若是就取后面的一个字符,一直往后;,那么递归的时候每次从包括目前正在递归的值开始遍历,也没有深度要求,那么当sum大于taget时就return,当sum==target就保存,当sum<target时就继续递归。
2023-05-05 22:29:36
251
原创 随想录训练营22/60 | LC 216.组合总和III;LC 17.电话号码的字母组合
k个数相加等于n,这k个数不能重复且只能从1到9中选,返回的是满足条件的所有k个数组成的vector。本题思路和 77.组合相同,k为二叉树深度,从i到9(i从1到9取值)为二叉树的孩子个数,进行递归。:用map将每个数字对应的字符串保存起来,按照输入的字符串(数字)进行递归遍历,递归的深度就是数字串的长度,每次递归的宽度就是数字对应的字符串长度。也可以将sum在递归中传入,回溯的时候也要对sum进行回溯。
2023-05-02 20:00:56
170
原创 随想录训练营21/60 | 回溯理论基础;LC 77. 组合
之前学习了二叉树的知识,遍历二叉树时,一般用递归法,在计算和深度高度相关的题时也用到了回溯。回溯即递归,有递归就可以有回溯。回溯的本质是穷举,穷举所有可能,不是一个高效的算法。为什么还要学习回溯呢?即使回溯效率低,但有些问题只能通过穷举法解决,如:组合问题;切割问题;子集问题;排列问题;棋盘问题。,以上问题本质都是,集合的大小就是树的宽度,递归的深度就是树的深度。与之前学习的三部曲相同:先确定递归的返回值和参数;回溯一般没有返回值(void),参数比二叉树难,一般是根据递归逻辑确定参数。
2023-05-02 14:54:38
96
原创 随想录训练营20/60 | LC 669. 修剪二叉搜索树;LC 108.将有序数组转换为二叉搜索树;LC 538.把二叉搜索树转换为累加树
本题是将不在规定范围内的节点,对于某些节点有两个孩子,但是要删除该节点,又要改变树的结构(像上一题)。但是该题中,若节点不在规定范围中,那么该节点的左子树也不在规定区间(节点小于规定区间)或者右子树不在规定区间(节点大于规定区间)。:将二叉搜索树中序遍历得到从小到大的有序数组,然后对数组从后向前遍历,每个值加上大于该值的所有值,也就是从后向前更新,每个值等于本身加上其右边一个值。:构建树是从根节点向下构建的,所以遍历数组要从中间开始向两边遍历来构建平衡二叉搜索树。:删除多个节点,上一章节的删除一个节点是。
2023-04-30 10:10:23
118
原创 随想录训练营19/60 | LC 235. 二叉搜索树的最近公共祖先 ;LC 701.二叉搜索树中的插入操作;LC 450.删除二叉搜索树中的节点
删除的节点若是叶子节点就容易;若是只有左子树或者右子树的节点也简单,只需将删除节点的父节点的子节点换位删除节点的子节点即可;**但是从上往下遍历,第一个属于p和q之间的节点就是p和q的最近公共祖先。注意终止条件是找到合适的新节点的位置就返回,递归的逻辑是通过val和二叉树的值比较进行递归。当遍历节点在p和q之间,那么该节点是公共祖先,但是不一定是最近的公共祖先(第一印象):上一章节求解了二叉树的最近公共祖先,本题可利用二叉搜索树的特性。当遍历节点比p和q都小的话那么就去右子树遍历;
2023-04-27 21:46:57
185
原创 随想录训练营18/60 | LC 530.二叉搜索树的最小绝对差;LC 501.二叉搜索树中的众数;LC 236. 二叉树的最近公共祖先
新思路:输入有要求首先二叉树的所有节点val互不相同,第二q和p都存在于给定二叉树中,因此只需判断节点的左右子树是否含有q或者p,若含有则直接返回,若不含有就继续递归。:中序遍历,统计每个数出现的频率,记录最大的频率,和最大频率的值,当出现相同的就将最大频率的值增添一个,当出现更大的频率就把之前保存的都删除添加新的。:利用二叉搜索树的特性,进行中序遍历,每次保存前面的值,让后面的值减去前面的值,若绝对值变小,就更新最小绝对差。
2023-04-26 21:47:43
209
原创 随想录训练营17/60 | LC 654.最大二叉树 ;LC 617.合并二叉树 ;LC 700.二叉搜索树中的搜索 ;LC 98.验证二叉搜索树
根节点的左子树是下次递归函数(左数组)的返回值,根节点的右子树是下次递归函数(右数组)的返回值。:判断二叉树是否时二叉搜索树,就前序遍历,看左节点是否小于根节点,看右节点是否大于根节点,若不满足上述条件就返回false;:构建最大二叉树,该二叉树的根节点是数组中的最大值,二叉树的左子树是由最大值的左边递归构建,二叉树的右子树是由最大值的右边递归构建。:递归遍历,当节点的值等于val就返回,当val大于节点值,就去右子树;:同时遍历两个二叉树,当同时存在节点时,就让两个节点的值相加;当都没有节点时,就为空。
2023-04-26 20:10:22
191
原创 随想录训练营16/60 | LC 513.找树左下角的值;LC 112. 路径总和;LC 113.路径总和ii;LC 106.从中序与后序遍历序列构造二叉树;LC 105.从前序与中序遍历序列构造二叉
找到最低层的最左节点。思路为用层次遍历,到最后一层,保存最左节点(最开始)。或者每层都保存最开始(最左)节点,最终输出。深度递归遍历也可以,不过不能只考虑叶子节点,应考虑。最左侧的值,不一定是左孩子节点。先遍历左边再遍历右边就可以。
2023-04-26 11:13:25
216
原创 随想录训练营15/60 | LC 110.平衡二叉树;LC 257. 二叉树的所有路径;LC 404.左叶子之和
通过这几天的实践,可以看出后序遍历在计算二叉树深度和节点高度时非常方便,前序遍历反而要考虑很多东西。当在统计二叉树的路径时,使用前序遍历比较合适。
2023-04-24 21:17:32
179
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅