- 博客(43)
- 收藏
- 关注
原创 代码随想录算法训练营第四十九天|接雨水、柱状图最大的矩形
首尾加0,首部加0是为了防止出现数组单调递减的情况,因为进行比较操作时需要三个元素。尾部加0是为了防止出现数组单调递增的情况,如果单调递增那么就无法进行到比较操作的步骤。思路:找到在左边和右边第一个比当前柱子矮的柱子,如果没有说明可以扩展到边界,右边减去左边索引再减一就是宽,当前柱子高度为高得到面积,不断更新结果取最大值。思路:找到当前柱子右边比它大的第一个柱子以及左边比它大的第一个柱子,使用单调栈存放结果即可实现。
2024-08-26 17:36:01 273
原创 代码随想录算法训练营第四十六天|回文子串、最长回文子序列
递推公式:当s[i]==s[j]时,有三种情况,第一种i=j此时肯定为回文子串,第二种j-i=1此时只有两个字符且相等也是回文子串,第三种情况j-i>1此时的dp[i][j]就和dp[i+1][j-1]有关了,如果dp[i+1][j-1]为true则i-j为回文子串。:当s[i]==s[j]时,dp[i][j]=dp[i+1][j-1]+2。j不取i然后取最大值,即dp[i][j]=max(dp[i][j-1],dp[i+1][j])。:最初始情况为i=j,所以将dp[i][j]=1(i==j)。
2024-08-21 12:27:10 430
原创 代码随想录算法训练营第四十五天|不同的子序列、两个字符串的删除操作、编辑距离
根据递推公式第一行和第一列需要初始化,对于第一行dp[0][j],使以-1为尾(空字符串)的word1和以j-1为尾的word2相同需要删除的步数就是当前word2的长度j,所以dp[0][j]=j。=word2[j],一共三种情况,删i-1就是dp[i-1][j]+1(其中dp[i-1][j]为使以i-2为尾的word1和以j-1为尾的word2相同需要删除的步数),删j-1就是dp[i][j-1]+1,i-1和j-2都删就是删两步,为dp[i-1][j-1]+2,然后三种情况取最小值。
2024-08-20 17:43:05 728
原创 代码随想录算法训练营第四十四天|最长公共子序列、不相交的线、最大子数组和、判断子序列
当text1[i-1]==text2[j-1]时,dp[i][j]=dp[i-1][j-1]+1。:由递推公式dp[i][j]可以由dp[i-1][j-1]、dp[i-1][j]、dp[i][j-1]得到,所以第一行和第一列需要初始化。其余格子也初始化为0。递推公式:两种情况,一种是延续前面的子序列,dp[i-1]+nums[i],另一种是从i开始重新产生一个子序列,nums[i],则递推公式为dp[i]=max(dp[i-1]+nums[i],nums[i])。初始化:dp[0]=nums[0]。
2024-08-20 11:01:33 890
原创 代码随想录算法训练营第四十三天|最长递增子序列、最长连续递增子序列、最长重复子数组
再加一个for循环遍历i之前的元素,当nums[i]>nums[j]时说明nums[i]可以接在nums[j]之和构成更长的递增子序列,所以递推公式取dp[i]=max(dp[j]+1,dp[i]);:因为是连续的那么只需要比较i和i-1即可,不用让i和i前面每一个元素都比较了,则递推公式为if(nums[i]>nums[i-1]) dp[i]=dp[i-1]+1。:dp[i][0],判断当nums1[i]=nums2[0]时dp[i][0]=1,dp[0][i]同理,其余格子初始化为0。
2024-08-19 18:40:51 305
原创 代码随想录算法训练营第四十二天|买卖股票最佳时机、买卖k次、含冷冻期、含手续费
dp[i][0]第i天持有股票的最大金额,dp[i][1]第i天保持卖出股票状态(冷冻期之和一直没有买入)的最大金额,dp[i][2]第i天卖出股票的最大金额,dp[i][3]第i天冷冻期最大金额。:dp[0][0]=-prices[i],dp[0][1]=0(如果是一个非法状态,那么就带入具体的值看看递推公式需要它初始化为多少),dp[0][2]=0,dp[0][3]=0。使用for循环实现。
2024-08-19 15:49:55 342
原创 代码随想录算法训练营第四十一天|买卖股票的最佳时机,只能买卖一次,可以买卖多次,最多买卖两次
对于dp[i][1]:第i天不持有股票同样也有两种情况,一种是第i天之前卖出股票就是dp[i-1][1],另一种情况是第i天卖出股票,为dp[i-1][0]+prices[i],则递推公式为:dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])。dp含义:dp[i][0]在第一次买入之前不操作,dp[i][1]持有第一支股票最大金额,dp[i][2]不持有第一支股票最大金额,dp[i][3]持有第二支股票最大金额,dp[i][4]不持有第二支股票最大金额。
2024-08-19 11:11:27 669
原创 代码随想录算法训练营第三十九天|打家劫舍
我们仔细分析上述三种情况,发现情况二和情况三是包含情况一的,例如情况二只考虑首元素和中间元素的最优解,里面肯定会包含不选首元素的情况就和情况一相同了,因为dp[i]的含义是房间i之前以及i可以偷到的最高金额为dp[i]。情况三同理也包含情况一。:首先考虑偷i房间的话,偷到的最大金额为:nums[i]+dp[i-2],不偷i房间的话,偷到的最大金额为:dp[i-1],则递推公式:dp[i]=max(dp[i-1],nums[i]+dp[i-2]);情况三:不选首元素,只考虑中间元素和尾元素的最优解。
2024-08-18 14:22:16 430
原创 代码随想录算法训练营第三十八天|零钱兑换、完全平方数、单词拆分、多重背包、背包总结
问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);问装满背包有几种方法:dp[j] += dp[j - nums[i]]问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j])
2024-08-16 17:19:25 696
原创 代码随想录算法训练营第三十七天|完全背包、零钱兑换Ⅱ、组合总和Ⅳ、爬楼梯进阶
有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。,求解将哪些物品装入背包里物品价值总和最大。。:01背包遍历背包时要倒序遍历,因为物品不能重复使用,而完全背包遍历背包时要正序遍历,因为物品可以重复使用。遍历物品和遍历背包的顺序随便,先遍历谁都可以(对于纯完全背包问题)。先遍历谁无非就是一行一行填还是一列一列填,只要当前格子的前面一个格子有值,就可以推出当前格子的值。
2024-08-16 15:05:04 265
原创 代码随想录算法训练营第三十六天|最后一块石头的重量、目标和、一和零
思路:相撞之后留下最小重量的石头,那么将石头分为两堆且重量相近,也就是取石头数组重量之和然后除以2,例如总重量为23,23/2=11,那么就分为11和12两堆相撞最后留下的就是最小重量。此时问题就转化为从石头数组中取石头构成重量为11的堆,为01背包问题。dp[j]的含义:总重量为j时可以容纳的最大重量。递推公式:本题物品的重量和价值都是石头的重量初始化:dp[i]=0。首先不能初始化为负数,其次如果初始化的数太大递推公式max可能会覆盖正确的取值导致出错,所以都初始化为0。遍历顺序。
2024-08-15 14:14:49 392
原创 代码随想录算法训练营第三十五天|背包问题理论基础、携带研究材料、分割等和子集
01背包:有n种物品,每种物品只有一个;完全背包:有n种物品,每种物品有无限个;多重背包:有n种物品,每种物品的个数各不相同。
2024-08-13 17:04:09 962
原创 代码随想录算法训练营第三十四天|不同路径、不同路径(有障碍)、整数拆分、不同的二叉搜索树
对于一个二维数组m,m.size()是数组的行数,m[0].size()是数组的列数。
2024-08-12 19:22:40 1601
原创 代码随想录算法训练营第三十二天|动态规划理论、斐波那契数、爬楼梯、最小花费爬楼梯
英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,,贪心没有状态推导,而是从局部直接选最优的。
2024-08-12 11:09:32 279
原创 代码随想录算法训练营第三十天|查找重叠区间、划分字母区间
难点就在于判断当前气球与上一个气球重叠之后,怎么判断下一个气球与当前气球是否重叠,就需要更新气球右边界。首先记录每一个字母出现的最远距离,然后便利字符串不断用当前字母出现最远距离更新右边界,直到右边界等于当前遍历位置,存结果,更新左边界继续向后遍历。首先对数组按照左边界从小到大排序,遍历数组,判断当前气球的左边界是否与上一个气球的右边界有重合,如果没有箭数加一,如果有则。本题和上一题类似都是找重叠区间,不同的是对结果的++,上一题是遇到不重叠的++,本题是遇到重叠的++。
2024-08-09 16:55:04 275
原创 代码随想录算法训练营第二十八天|买卖股票最佳时机、跳跃游戏、k次取反后最大化的数组和
之所以把cmp实现为静态函数,是因为静态函数可以在类中不依赖对象独立存在,不需要实例化对象也可以在类内直接使用。
2024-08-06 19:46:23 137
原创 代码随想录算法训练营第二十七天|贪心算法、分发饼干、摆动序列、最大子数组和
例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?指定每次拿最大的,最终结果就是拿走最大数额的钱。每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。
2024-08-06 15:46:28 281
原创 代码随想录算法训练营第二十五天|非递减子序列、全排列、重新安排行程、N皇后、解数独
其中 ++符号是对targets中嵌套的map中对应键的值进行自增操作。具体解释一下:targets[vec[0]],首先,使用vec[0]作为外层unordered_map的键来查找或创建一个键值对。如果这个键值对不存在,则会创建一个新的map<string,int>并将其与vec[0]键关联起来。vec[1],接着,使用vec[1]作为内层map的键来查找或创建一个键值对。如果这个键值对不存在,则会创建一个新的int值并将其与vec[1]键关联起来。
2024-08-05 21:48:22 670
原创 代码随想录算法训练营第二十四天|复原IP地址、子集、子集Ⅱ
单层搜索逻辑,从分割线开始for循环遍历宽度,分割线不动for循环控制i++,从startIndex到i分割,如果有效则在i后面加逗点,之后从i+2(因为加了一个逗点)处开始下一层递归(深度),递归之后回溯。之前的回溯都是在递归结束时收获结果,这道题需要在树中的每一个节点收获结果。vec.insert(s.begin,i)在第一个元素后面插入i,vec.erase(s.begin()),删掉第一个元素。回溯三部曲,确定返回值和参数,参数为传入的字符串,分割线startIndex,加入逗点的次数。
2024-08-01 11:23:58 304
原创 代码随想录算法训练营第二十三天|组合,组合(去重),分割回文字符串
具体实现去重使用used数组,大小和等于目标数组大小,其中与目标数组对应索引放得是bool值类型初始化为false,当数组中某一个元素使用放入到path集合之后,对应索引的used数组中置为true,代表这个元素已经被使用过了。去重逻辑:题目中给的数组中是包含重复数字的,排序之后,进行树层去重,因为相同的元素排序之后是相邻的,一个元素a进行遍历他后面的元素组合后,如果再取与a相同的元素b遍历b之后的元素组合,必定会出现重复的组合,所以进行树层去重。for循环遍历宽度,递归遍历深度。
2024-07-31 16:47:20 367
原创 代码随想录算法训练营第二十二天| leetcode 11、216、17
在1到n中取k个数进行组合,如果我们已经取了m个数,还需要取k-m个数,所以我们最多要从n-(k-m)+1处开始取,再往后就取不到k个数了,就是我们要减枝处理的部分。1.index为digits的索引,当index=digits.size()-1时还需要往s里面添加一个字母,所以循环结束条件应该是index==digits.size()。2.在C++中,字符的ASCII码值可以直接进行算术运算。
2024-07-25 21:14:30 276
原创 代码随想录算法训练营第二十一天| leetcode 659、108、538
首先处理头节点,让新的头节点处于区间之内,此时头节点的左孩子一定是处于区间只能或在区间左边,只需要处理在区间左边的情况,也就是删掉左孩子本身以及左孩子的左子树。这是删掉左孩子以及左孩子的左子树操作,要使用while循环删除,使用if的话只能闪删一次,如果左孩子的右孩子(会作为下一次迭代的左孩子)的val也小于low的话就删不掉了。1.平衡二叉搜索树左右子树的绝对值不超过1,所以可以把数组从中间分开,中间的数作为根节点,左右两边分别构造左子树和右子树。累加要从最大值开始累加,所以遍历顺序为右中左。
2024-07-25 15:31:43 398 1
原创 代码随想录算法训练营第二十天| leetcode 235、701、450
遍历整个二叉树的节点搜寻目标值,找到目标节点如果其右孩子为空,则直接返回左孩子,如果右孩子不为空,就将右孩子最左边的叶子节点与目标节点的val值交换,然后继续迭代,当再次找到目标值时目标节点肯定是叶子节点,然后返回其左孩子也就是null,删除节点。如果q和p的val都大于当前根节点的val,那么遍历根节点的右子树,如果q和p的val都小于当前根节点的val,那么遍历根节点的左子树。则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上。2.删除的节点为叶子节点,左右都为空。
2024-07-23 17:07:50 401
原创 代码随想录算法训练营第十八天| leetcode 530、501、236
1.想要不断更新得到最小值,那么一开始res结果就要是最大值。2.为什么要判断pre不为空,不判断就会出错?因为pre初始化为空,在第一次迭代的时候还没有用cur跟新pre,所以需要判断。
2024-07-22 15:41:06 281
原创 代码随想录算法训练营第十七天| leetcode 654、617、700、98
还是太菜了我,还得练,一个while循环就可以解决得问题,想得太复杂。
2024-07-22 10:19:25 282
原创 代码随想录算法训练营第十六天| leetcode 513、112、106、105
1.不用对根节点进行操作,所以前后中序都可以,只要先左就行。2.递归需要传入的参数是根节点和当前节点的深度,递归结束的条件是当前节点的左右孩子都为空则更新深度更新res,单层递归需要做的就是遍历当前节点的左右孩子,前提是左右孩子不为空(这样就不用判断根节点是否为空了)。将回溯的过程隐藏,因为此时调用递归函数传深度时是值传递,我们直接传入depth+1,不会改变depth的值。1.递归传入的参数是当前遍历节点和一个计数变量,递归结束条件是遍历到叶子节点如果计数器为0返回true不为0返回false。
2024-07-19 18:22:53 366
原创 代码随想录算法训练营第十五天| leetcode 222、110、257、404
1.回溯和递归是一一对应的,有一个递归,就要有一个回溯,回溯要和递归永远在一起。2.to_string()函数将数值类型变量转化为字符串类型。
2024-07-18 21:15:37 429
原创 代码随想录算法训练营第十四天| leetcode 226、101、104、111
其中中序遍历与前序遍历和后序遍历的递归不同,在遍历右孩子之前已经对根节点操作翻转了根节点的左右子树,所以最后一步依然要遍历左孩子。
2024-07-16 19:38:06 171
原创 代码随想录算法训练营第十一天| leetcode 150、239、347
1.long long:是 C++ 中的一种整数类型,通常至少有 64 位(8 字节)。这意味着它可以表示的整数范围至少是从 -2^63 到 2^63 - 1。2.stoll:是 C++ 标准库中的一个函数,属于头文件,用于将一个字符串转换为一个long long类型的整数。1.当使用greater作为比较函数时,优先级队列会认为较大的元素具有较低的优先级。因此,最小的元素会位于堆的顶部,从而形成小根堆。2.因为小顶堆先弹出的是最小的,所以倒序输入到数组。
2024-07-15 14:08:50 580
原创 代码随想录算法训练营第十天| leetcode 232、225、20、1047
1.使用两个栈,一个stackIn压入元素模仿队列入队(stackIn的栈顶就是队列的队尾),另一个栈stackOut接受stackIn弹出元素并压入栈内(stackOut的栈顶就是队列的队头)。当stackOut为空,stcakIn不为空时将stackIn中所有元素弹出并压入stackOut。2.peek函数中,使用this指针可以避免代码重用。1.队列模仿入栈,就是que1队尾入即可。
2024-07-14 18:16:40 1557
原创 代码随想录算法训练营第九天| leetcode 151、28、459、卡码网55、KMP算法
1.实现了一个左闭右闭翻转字符串的reverse函数。2.基于双指针的思想实现了一个删除字符串多余空格的removeExtraSpaces函数。快指针用于查找更新数组的元素,慢指针负责指向需要更新的位置和在除了第一个单词之外的每个单词前加空格。fast快指针遍历整个字符串,直到找到不为空的位置,每找到不为空的位置就说明找到了第一个单词或者一个新的单词,除了第一个单词之外剩余的单词前使用慢指针加空格,之后使用while循环将每一个单词更新到数组中新的位置。
2024-07-13 18:41:14 1853
原创 代码随想录算法训练营第八天| leetcode 344、541、卡码网54
交换的时候可以使用swap(s[index1],s[index2]);index2--;将字符串s从索引i到(i+k-1)的元素反转,C++库函数保持左开右闭原则。1.新数组从后向前填充避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。2.while(cin>>s),当输入流cin成功读取一个字符串到s变量时,就执行循环体内的代码。这个循环会一直持续直到从cin读取字符串失败。改变字符串大小。
2024-07-10 13:52:52 498
原创 代码随想录算法训练营第七天|四数相加Ⅱ、三数之和双指针解法、四数之和双指针解法
我写这道题遇到的问题就是,怎么保存sum1在前两个数组元素和中出现的次数,我写得很复杂,卡哥写得是map[a+b]++;这样写可以直接映射到key为(a+b)对应得value值并通过“++”让其自增,如果没有key值为(a+b)的相当于直接insert(a+b,0)++,还使用范围for循环简化了代码,又学到一招。1.对于第一个元素去重的逻辑不能写成if(nums[i]==nums[i+1]),因为我们要找的是不重复的三元组,但三元组内的元素是可以重复的。
2024-07-09 22:03:20 401
原创 代码随想录算法训练营第六天|哈希理论基础、有效字母异位词、快乐数、两数之和
1.先对两个数组从小到大排序,i指针和j指针分别指向两个数组的起始位置,然后判断nums1[i]和nums2[j]的大小,如果相等则将nums1[i]放入结果,之后两个指针同时向后移动一位,如果nums1[i]
2024-07-08 15:37:57 792 1
原创 代码随想录算法训练营第四天|两两交换链表中的节点、删除倒数第N个节点、相交链表、环形链表
nullptr)如果这样写一旦cur->next为空那么cur->next->next就会出错相当于对空指针取值,需要注意!2.在使用虚拟头节点之后,链表的头节点就变成虚拟头节点了,那么最后返回不能直接return head;1.卡哥代码随想录公众号中的操作是,先让fast指针走n+1步然后快慢指针一起移动直到fast!=nullptr,我是先让fast走n步然后快慢指针一起移动直到fast->next!=nullpttr,这两种方法都可以让slow慢指针指向倒数第n个节点的前一个节点进行操作。
2024-07-06 17:27:24 440 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人