
代码随想录
代码随想录
Stay Peace
这个作者很懒,什么都没留下…
展开
-
数据流的中位数
新的中位数将小于等于原来的中位数,因此我们可能需要将queMin中最大的数移动到queMax中。新的中位数将大于等于原来的中位数,因此我们可能需要将queMax中最小的数移动到queMin中。当累计添加的数的数量为奇数时,queMin中的数的数量比queMax多一个,此时中位数为queMin的队头。是有序整数列表中的中间值。当累计添加的数的数量为偶数时,两个优先队列中的数的数量相同,此时中位数为它们的队头的平均值。特别地,当累计添加的数的数量为0时,我们将num添加到queMin中。原创 2025-03-03 20:37:14 · 235 阅读 · 0 评论 -
旋转字符串
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。用空间复杂度为O(1)的原地算法解决这个问题。b.反转区间为n到末尾的子串。c.反转区间为n到末尾的子串。a.反转区间为前n的子串。b.反转区间为前n的子串。原创 2025-02-10 10:35:06 · 141 阅读 · 0 评论 -
单调栈类型
更直白来说,就是用一个栈来记录我们遍历过的元素,因为遍历数组的时候,不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以需要用一个容器(这里用单调栈)来记录遍历过的元素。单调栈解决的问题通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时就要想到可以用单调栈。如果求一个元素右边第一个更大元素,单调栈就是递增的,如果求一个元素右边第一个更小元素,单调栈就是递减的。依次从单调栈中弹出多个元素,直到单调栈为空或者栈顶元素大于当前遍历的元素为止。原创 2025-02-05 15:40:20 · 235 阅读 · 0 评论 -
动态规划解决子序列问题
给你一个整数数组nums ,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如[3,6,2,7] 是数组[0,3,1,6,2,2,7] 的子序列。位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。这里采用一维dp数组的形式,数组的长度为整数数组nums的长度,其中每个元素。dp[i]是有0到i-1各个位置的最长递增子序列 推导而来,那么遍历。注意不是要dp[i]与dp[j] + 1进行比较,而是。原创 2025-01-21 17:47:50 · 302 阅读 · 0 评论 -
最佳股票买卖时机问题
其中,对于dp[i][1],由于其表示的是第i天不持有股票所能获得的最大利润,因此其有两种推导方法,第一种是保持第i-1天的状态,也就是第i-1天不持有股票,第i天同样不持有股票而不购入,此时对应的值为dp[i-1][1];其中,对于dp[i][0],由于其表示的是第i天持有股票所能获得的最大利润,因此其有两种推导方法,第一种是保持第i-1天的状态,也就是第i-1天持有股票,第i天同样持有股票而不售出,此时对应的值为dp[i-1][0];对于每一天i,需要有dp[i][0]和dp[i][1]需要获得。原创 2025-01-16 16:09:17 · 441 阅读 · 0 评论 -
打家劫舍问题
从第i个房屋中获得现金,此时需要该房屋的前一个房屋不能被偷盗,因此获得的金额为dp[i - 2] + nums[i],也就是第i-1房一定是不考虑的,找出下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。dp数组的长度为房屋数组的长度,其中每个元素dp[i]表示考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]如果不偷第i房间,那么dp[i] = dp[i - 1],即考虑i-1房,(注意这里是考虑,并不是一定要偷i-1房。这个地方所有的房屋都。原创 2025-01-15 19:53:40 · 392 阅读 · 0 评论 -
动态规划解决单词拆分问题
这里采用一维数组的形式,其中数组长度为目标字符串s的长度+1,其中每个元素dp[i]表示字符串长度为i的话,dp[i]为true则可以拆分为一个或多个在字典中出现的单词。dp[i]的状态依靠dp[j]是否为true,那么dp[0]就是递推的根基,dp[0]一定要为true,否则递推下去后面都都是false。如果确定dp[j]是true,且[j, i]这个区间的子串出现在字典里,那么dp[i]一定是true。对于dp数组中的每个位置的元素dp[i]来说,其值取决于前面的元素dp[j]原创 2025-01-14 14:43:45 · 279 阅读 · 0 评论 -
动态规划解决零钱兑换问题
采用一维数组的形式,其中数组长度为amount+1,数组中的每个元素dp[j]表示凑足总额为j所需钱币的最少个数为dp[j],否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。所以dp[j]要取所有dp[j - coins[i]] + 1中最小的。首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;每种硬币的数量是无限的,可以看出是典型的完全背包问题。dp问题求解最大值:dp[j]初始化为最小值。就是dp[j](考虑coins[i])原创 2025-01-13 20:54:19 · 296 阅读 · 0 评论 -
动态规划解决组合总和问题IV
因为递推公式dp[i] += dp[i - nums[j]]的缘故,dp[0]要初始化为1,这样递归其他dp[i]的时候才会有数值基础。dp[i](考虑nums[j])可以由dp[i - nums[j]](不考虑nums[j])推导出来。因为只要得到nums[j],排列个数dp[i - nums[j]],就是dp[i]的一部分。其余下标的元素初始化为0,这样才不会影响dp[i]累加所有的dp[i - nums[j]]这里采用一维数组的形式,其中dp[i]表示凑成目标正整数为i的排列个数为dp[i]原创 2025-01-10 14:16:52 · 354 阅读 · 0 评论 -
动态规划解决完全背包问题
第i件物品的重量是weight[i],得到的价值是value[i]。放物品i,背包需要空出物品i的容量,此时背包容量为j - weight[i],dp[i][j - weight[i]] 为背包容量为。dp[i][j]表示从下标为[0-i]的物品,每个物品可以取无限次,放进容量为j的背包,价值总和最大是多少。其中,对于第一列元素,由于此时的背包容量为0,因此无法装入物品,所以第一列的元素均为0。不放物品i,此时背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]需要初始化第一行和第一列。原创 2025-01-09 22:01:22 · 370 阅读 · 0 评论 -
动态规划解决零和一问题
因此递推公式为:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);字符串的zeroNum和oneNum相当于物品的重量(weight[i]),字符串本身的个数相当于物品的价值(value[i])dp[i][j]可以由前一个strs里的字符串推导出来,strs里的某一个字符串有zeroNum个0,oneNum个1。dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]在遍历的过程中,取dp[i][j]的最大值。原创 2025-01-09 12:01:10 · 242 阅读 · 0 评论 -
动态规划解决目标和问题
可以将数组分为两部分,其中一部分记作left,其中数字的符号全为+,而另外一部分记作right,其中数字的符号全为-。这里全为-的意思不是真正的符号为-,而表示这一堆数字在计算时取值为负left + right = sum,其中sum为数组和left - right = target,其中target为目标值可以得出left = (sum + target) / 2因此原问题转换为在集合nums中找出和为left的组合共有多少种也就是用nums装满容量为x的背包,有几种方法。原创 2025-01-07 21:45:28 · 925 阅读 · 0 评论 -
动态规划局解决分割等和子集问题
如果背包所载重量为target, dp[target]就是装满 背包之后的总价值,因为本题中每一个元素的数值既是重量,也是价值,所以当dp[target] == target的时候,背包就装满了。这里采用一维数组,dp[j]表示容量(所能装的重量)为j的背包所背的物品价值最大可以为dp[j]当数字可以装满承载重量为sum / 2的背包的背包时,这个背包的价值也是sum / 2。既有一个只能装重量为sum / 2的背包,商品为数字,这些数字能不能把这个背包装满。一个数字只有一个维度,即重量等于价值。原创 2025-01-06 20:37:37 · 361 阅读 · 0 评论 -
动态规划解决0-1背包问题
如果j>=weight[i],则dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weight[i]+value[i]);对于第一行来说,判断背包的容量是否能装入第0件物品,如果可以,则该位置的值为第0件物品的值,否则为0。其中,对于第一列来说,由于此时背包的容量为0,因此无法装入物品,所以第一列的值都为0。否则不能装入第i件物品,此时dp[i][j] = dp[i-1][j]此时背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]的容量后,背包容量为。原创 2025-01-03 14:53:34 · 321 阅读 · 0 评论 -
动态规划解决不同的二叉搜索树问题
所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2],当根节点为j时,它的左子树只能包含j-1个节点,而右子树包含i-j个节点。从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,这是可以说得通的。也可以理解是i个不同元素节点组成的二叉搜索树的个数为dp[i]dp[i]:1到i为节点组成的二叉搜索树的个数为dp[i]有2个元素的搜索树数量就是dp[2]。有1个元素的搜索树数量就是dp[1]。有0个元素的搜索树数量就是dp[0]。原创 2025-01-02 20:58:09 · 331 阅读 · 0 评论 -
动态规划解决整数拆分问题
注意这里在确定dp[i]时从1到i遍历j时更新dp[i]需要比较三个内容,分别是原始的dp[i],j*(i-j)以及j*dp[i-j],取这三个数的最大值更新dp[i],从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议。j的结束条件是 j < i - 1 ,其实 j < i 也是可以的。遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]dp[i]:分拆数字i,可以得到的最大乘积为dp[i]其实可以从1遍历j,然后有两种渠道得到dp[i].严格从dp[i]的定义来说,原创 2025-01-02 20:36:51 · 554 阅读 · 0 评论 -
动态规划解决步骤
5.返回最终结果,如果中途出现错误可以将dp数组打印出来。1.确定dp数组的含义,以及确定dp数组的大小和维度。4.确定遍历顺序,遍历dp数组并进行赋值。2.确定问题中的递推公式。原创 2025-01-01 15:05:30 · 400 阅读 · 0 评论 -
贪心算法解决单调递增数字问题
从后遍历数字中的每一位,如果遍历到第i位数字时它的前一位数字比它大(严格大于),令它前一位数字减1,同时令flag=i。遍历结束后,令该数字的第flag位及其之后的全部数字都变成9。定义一个变量flag,表示需要将之后的数字全部变成9的位置。最后返回最终的数字即可。原创 2024-12-27 15:39:54 · 685 阅读 · 0 评论 -
贪心算法解决监控二叉树问题
如果该节点不为空,依次获取该节点的左子结点的状态和右子节点的状态。如果左子结点和右子节点有一个节点的状态为无覆盖(0),那么令count++,同时在该节点处安装一个摄像头,返回1;为了让摄像头数量最少,我们要尽量让叶子节点的父节点安装摄像头,这样才能摄像头的数量最少。那么空节点不能是无覆盖的状态,这样叶子节点就要放摄像头了,空节点也不能是有摄像头的状态,这样叶子节点的父节点就没有必要放摄像头了,而是可以把摄像头放在叶子节点的爷爷节点上。所以把摄像头放在叶子节点的父节点位置,才能充分利用摄像头的覆盖面积。原创 2024-12-27 15:35:46 · 422 阅读 · 0 评论 -
划分字母区间
设置一个left变量和right变量,分别表示区间的左端点和右端点。从头遍历一遍字符串,并更新右端点,right = max(right,a[s.charAt(i)-'a'])为字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等,则找到了分割点。此时结果数组增加(right-left+1),同时更新left = right。遍历一遍字符串,统计每一个字符最后出现的位置。可以预先设置一个大小为26的数组,其中每个位置的元素代表该位置的小写字母最后出现的位置。原创 2024-12-25 14:42:46 · 248 阅读 · 0 评论 -
贪心算法解决用最少数量的箭引爆气球问题
要想射出的弓箭最少,需要统计重叠的气球的数量,如果多个气球重叠的话使用一支箭即可。首先对数组中每个子数组进行排序,排序的规则是它们的第一个元素从小到大的顺序。从第一个子数组开始遍历数组中的全部子数组,如果当前遍历的。,那么表示这两气球不重叠,此时。否则表示这两个气球重叠,此时。原创 2024-12-24 14:52:41 · 537 阅读 · 0 评论 -
贪心算法解决根据身高重建队列问题
本题有两个维度h和k,一定要想如何确定一个维度,然后再按照另一个维度重新排列。优先按身高高的people的k来插入。插入操作过后的people满足队列属性。最后都做完插入操作,整个队列满足题目队列属性。对原数组进行排序,让。原创 2024-12-23 14:39:14 · 375 阅读 · 0 评论 -
贪心算法解决分发糖果问题
由于每个孩子都要得到一块糖果,因此初始化一个全为1的数组,该数组的长度等于孩子的个数。从前往后遍历,如果位置i处的孩子对应的分数大于位置i-1处的孩子的分数,令。两次遍历结束后,统计数组中的每个元素之和,即表示获得的最终结果。从后往前遍历数组中的每个元素,如果。原创 2024-12-20 18:34:44 · 458 阅读 · 0 评论 -
贪心算法求解加油站问题
依次遍历差距数组中的每个元素,每遍历一个就更新cursum和totsum,之后判断cursum是否小于0,如果小于0则表示从start出发无法遍历全部的加油站,同时置start为i+1以及将cursum置于0。遍历完毕全部的元素之后,判断totsum是否小于0,如果小于0表示无法找到合适的出发位置能够遍历整个数组,此时返回-1,否则变量start表示的便是能够出发遍历全部加油站的起始位置,将其返回即可。首先构造一个差距数组diff,其中每个位置的值都是gas数组和cost数组对应位置的值的差。原创 2024-12-20 18:29:38 · 382 阅读 · 0 评论 -
贪心算法求解跳跃游戏
那么表示能够跳到数组最后的位置,因此返回true。如果循环结束后没有返回值,那么返回false。因此设置一个变量表示每次移动时能够覆盖的范围,该变量的初始值为0。求解是否能够跳到数组的最后一个位置,关键在于跳跃的覆盖范围。,同时更新该覆盖范围变量的取值。每次更新时该变量取值是。原创 2024-12-18 19:20:26 · 412 阅读 · 0 评论 -
贪心法求解最大子序列之和
初始化maxSum=Integer.MIN_VALUE,表示最大子序列之和。更新sum之后,如果sum>maxSum,则令maxSum=sum。遍历数组中的每一个数据,每遍历一个,令sum+=nums[i]更新sum之后,如果sum<0,则令sum=0。初始化sum=0,记录当前子序列之和。最后返回maxSum即可。原创 2024-12-17 14:52:57 · 203 阅读 · 0 评论 -
贪心法求解摆动序列
如果preDiff>=0&&curDiff<0或者preDiff<=0&&curDiff>0,则将result+1,并且将preDiff置成curDiff。初始化记录结果的变量result=1,初始化为1的原因在于序列默认最右边那个元素有一个峰值。判断是否是摆动序列中的节点只需要看该节点与其左边节点的差和右边节点的差符号是否相反即可。每遍历一个,求解curDiff=(nums[i+1]-nums[i])遍历数组中第一个到倒数第二个元素。初始化preDiff=0。初始化curDiff=0。原创 2024-12-17 14:49:59 · 240 阅读 · 0 评论 -
回溯算法解决重复行程问题
如果该元素位置为0的字符串与保存最终结果列表的最后一个元素相等,则将该元素的第2个元素加入到最终结果中,同时置该元素为已经访问过。之后进入下一层递归,如果该层返回值为true,则直接返回true,表示已经找到了一个合适的解,否则进行回溯,保存结果的数组删除掉最后一个元素,同时置该元素为未被访问过。当保存最终结果的数组的大小为tickets数组的大小+1时,此时表示已经找到了一个结果,直接返回true。如果该元素没有被使用过,那么进一步处理,否则直接判断下一个元素。如果所有的元素都遍历过,返回false。原创 2024-12-12 20:33:17 · 201 阅读 · 0 评论 -
回溯法解决9*9的数独问题
如果位置(i,j)能够放下此时遍历的数据,则将数组对应位置进行修改,同时判断下一次回溯的返回值,如果返回值为true则返回true。判断位置(i,j)所在的3*3的方格内是否有一个数和num相等,有则返回false。所需要的参数:需要判断的数组,需要判断的位置(i,j)以及需要判断的数据num。判断位置(i,j)的同一行是否有一个数和num相等,有则返回false。判断位置(i,j)的同一列是否有一个数和num相等,有则返回false。方格的起始坐标为(3*(i/3),3*(j/3))原创 2024-12-12 20:23:13 · 203 阅读 · 0 评论 -
三数之和和四数之和
判断当前三个数的和是否等于0,如果大于0,则将right左移,如果小于0则将left右移,如果等于0,则表示找到当前一个符合条件的结果,进行保存。保存后对b和c进行去重处理,去重时不断移动right或left,移动的条件为nums[right-1]==nums[right]&&left<right以及nums[left+1]==nums[left]&&left<right。对a进行去重处理,如果i大于0并且nums[i]==nums[i-1],跳过当次循环。left和right的操作同三数之和。原创 2024-12-01 10:21:36 · 337 阅读 · 0 评论 -
修剪二叉树
如果不为空,判断当前节点值和high的大小,如果当前节点的值大于hight,则递归删除当前节点的左子树并返回左子树。如果不为空,且当前节点的值在low和high区间,则递归删除当前节点的左子树并将返回值赋值给当前节点的左子树。如果不为空,且当前节点的值在low和high区间,则递归删除当前节点的右子树并将返回值赋值给当前节点的右子树。如果不为空,判断当前节点值和low的大小,如果当前节点值小于low,则递归删除当前节点的右子树并返回右子树。判断当前节点是否为空,如果为空则直接返回。原创 2024-11-28 17:02:31 · 207 阅读 · 0 评论 -
二叉搜索树删除节点
如果左右子树都不为空,需要将该节点的左子结点赋值给该节点右子节点的最左侧的节点,同时返回该节点的右子节点,表示删除该节点后用该节点的右子节点补位。如果当前节点的值大于待删除的key,则递归删除该节点的左子结点,并将返回值赋给该节点的左子结点。如果当前节点的值小于待删除的key,则递归删除该节点的右子节点,并将返回值赋给该节点的右子节点。如果右子树不为空而左子树为空,则返回当前节点的右子节点,表示删除该节点后用它的右子结点补位。判断当前节点是否为空,如果为空表示删除的节点不存在,直接返回null。原创 2024-11-28 16:41:25 · 224 阅读 · 0 评论 -
链表中是否存在环
当确定存在环后设置一个新的指针从相交处每次移动一个单位,同时新增一个指针从头结点开始移动,每次移动一个单位,这两个指针必定会相交,并且相交处一定是环的入口位置。定义一个快指针和一个慢指针,快指针每次移动两个单位,慢指针每次移动一个单位,如果两个指针能够相等,那么链表中存在环,若快指针为null,不存在环。原创 2024-11-23 21:50:35 · 250 阅读 · 0 评论 -
两个链表相交
设置两个指针分别指向两个链表的头结点,先让长链表的指针移动(长度差)距离,然后分别移动两个指针,如果遇到两个指针相等就返回true,否则当两个链表全为null时返回false。计算两个链表的长度差。原创 2024-11-23 21:23:10 · 222 阅读 · 0 评论 -
二叉树的所有路径
递归函数的三个参数,分别表示当前遍历的节点、存储的当前路径和存储的全部路径。递归结束返回后需要回溯。原创 2024-11-19 14:14:42 · 203 阅读 · 0 评论 -
二叉树的前中后序遍历
需要用栈实现,前序和后序类似,中序遍历需要额外引入一个新的指针;需要搞清楚处理节点和遍历节点的顺序;栈中存放的数据类型为树的节点而不是树中节点的值。三种遍历方式代码结构相似,需要搞清楚三个内容:递归函数的返回值,递归函数传递的参数以及递归函数结束的条件。原创 2024-11-09 15:38:10 · 245 阅读 · 0 评论 -
Java中的优先级队列PriorityQueue集合
代码随想录原创 2024-11-07 14:41:01 · 117 阅读 · 0 评论 -
滑动窗口最大值
代码随想录原创 2024-11-06 16:00:20 · 102 阅读 · 0 评论 -
KMP算法
代码随想录原创 2024-11-01 15:24:50 · 284 阅读 · 0 评论