- 博客(85)
- 收藏
- 关注
原创 贪心算法---根据身高重建队列
先考虑身高,再考虑人数。将数组按照身高降序排列,身高相同的按照人数升序排列。将排好序的people数组元素一个一个插入到队列中,ki就是该元素的下标。表示队列中一些人的属性(不一定按顺序)。返回的队列应该格式化为数组。假设有打乱顺序的一群人站成一个队列,数组。请你重新构造并返回输入数组。是排在队列前面的人)。
2024-08-28 20:54:59
74
原创 贪心算法--柠檬水找零
当顾客支付5元时,直接收;当顾客支付10元时,找5元;当顾客支付20元时,优先找一张10元,一张5元,否则再考虑三张5元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付。如果你能给每位顾客正确找零,返回。顾客排队购买你的产品,(按账单。在柠檬水摊上,每一杯柠檬水的售价为。每位顾客只买一杯柠檬水,然后向你付。注意,一开始你手头没有任何零钱。支付的顺序)一次购买一杯。
2024-08-28 19:24:35
47
原创 贪心算法---分发糖果
第二次从右到左遍历,只比较左边大于右边的情况,如果ratings[i]>ratings[i+1],则ratings[i]=max(ratings[i+1]+1,ratings[i])第一次从左到右遍历,只比较右边大于左边的情况,如果ratings[i]>ratings[i-1],则ratings[i]=ratings[i-1]+1,否则为1。请你给每个孩子分发糖果,计算并返回需要准备的。思路:使用两次贪心思想。表示每个孩子的评分。
2024-08-26 11:23:05
386
原创 贪心算法---加油站
每个加油站的剩油量rest[i]为gas[i]-cost[i],i从0开始累加rest[i],和记为curSum,一旦curSum小于0,说明[0,i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到这里都会断油,所以起点为i+1,curSum归0。如果总油量减去总消耗大于等于0,那么一定可以跑完一圈,说明各个站点的加油站剩油量rest[i]之和是大于等于0的。,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回。你从其中的一个加油站出发,开始时油箱为空。
2024-08-26 10:19:10
300
原创 贪心算法---K次取反后最大化的数组和
2.装箱:boxed()将IntStream中的基本类型int转换为Stream<Integer>,即包装为Integer对象。思路:先将数组中所有负数按照绝对值由大到小依次取反,如果此时k还不为0,则反复将最小元素取反直至k为0。1.转换为流:IntStream.of(nums)将给定的nums数组转换为IntStream。5.收集为数组:toArray()将IntStream中的元素收集到一个数组中。以这种方式修改数组后,返回数组。可以多次选择同一个下标。2.计算和:利用流的。
2024-08-25 14:29:43
401
原创 贪心算法---跳跃游戏(2)
有一个特殊情况需要考虑,当移动下标达到了当前覆盖的最远距离下标时,如果当前覆盖最远距离下表不是集合终点,步数加一,还要继续走;如果当前覆盖最远距离下标是集合终点,部署不用加一,因为不能再往后走了。统计两个覆盖范围,当前这一步的最大覆盖范围和下一步最大覆盖范围。如果移动下标到了当前这一步的最大覆盖最远距离,还没有到达终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。从覆盖范围出发,不管怎么跳,覆盖范围内一定可以跳到,以最小步数增加覆盖范围,覆盖范围一旦覆盖了终点得到的就是最小步数。
2024-08-25 14:03:26
797
原创 贪心算法---跳跃游戏
思路:求局部最优解:每次取最大跳跃步数(取最大覆盖范围),每移动一个单位,就更新最大覆盖范围。整体最优解:最后得到整体最大覆盖范围,看是否能到终点。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回。给你一个非负整数数组。
2024-08-16 16:00:46
337
原创 贪心算法---买卖股票的最佳时机(2)
如prices=[7,1,5,3,6,4],利润为[-6,4,-2,3,-2],总利润为4+3=7。思路:求局部最优,累加每天的正利润,收集正利润的区间就是买卖股票的区间。在每一天,你可以决定是否购买和/或出售股票。你也可以先购买,然后在。
2024-08-16 15:13:00
202
原创 贪心算法---最大子数组和
思路:求局部最优,当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。是数组中的一个连续部分。
2024-08-16 15:00:04
99
原创 贪心算法---摆动序列
思路:curDiff记录当前差值,preDiff记录上一个差值,count记录序列长度。如果cueDiff与preDiff一正一负,则count+1,遍历整个序列。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为。
2024-08-13 18:15:52
292
原创 贪心算法---分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。,这是能让孩子们满足胃口的饼干的最小尺寸;将胃口,饼干尺寸都由小到大排序,最大的胃口优先得到满足。,我们可以将这个饼干。
2024-08-13 17:24:59
1033
原创 回溯法---解数独
第三步:确定单层递归逻辑。一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性。第一步:确定参数与返回值。参数为二维数组board,代表数独局势。返回值为布尔类型,找到一个符合的条件(就在树的叶子节点上)立刻就返回。第二步:确定终止条件。本题递归不用终止条件,解数独是要遍历整个树形结构寻找可能的叶子节点就立刻返回。编写一个程序,通过填充空格来解决数独问题。数独部分空格内已填入了数字,空白格用。
2024-08-13 17:08:07
175
原创 回溯法---N皇后
第三步:确定单层递归逻辑。for循环遍历棋盘每一列,如果棋盘局势合法,则将(row,col)坐标的元素设为Q,再递归回溯。第一步:确定参数与返回值。参数为棋盘行/列数n,树的深度row,棋盘局势chessboard,无返回值。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。第二步:确定终止条件。当row=n时,说明到达叶子节点,将结果存入结果集中。的棋盘上,并且使皇后彼此之间不能相互攻击。的棋子放置方案,该方案中。每一种解法包含一个不同的。分别代表了皇后和空位。
2024-08-11 17:28:31
178
原创 回溯法---全排列(2)
第三步:确定单层递归逻辑。for循环遍历整个nums数组,当i>0且nums[i]=nums[i-1]且used[i-1]=false时,说明同一树层中已经取过该元素了,直接跳过该元素的树枝。当used[i]=false时,将元素加入path中,再递归回溯。第二步:确定终止条件。当path中的元素个数等于nums数组中的元素个数时,说明组成了一种全排列结果,将结果加入结果集中。第一步:确定参数与返回值。参数为数组nums,记录元素使用情况的布尔数组used,无返回值。题目:给定一个可包含重复数字的序列。
2024-08-11 15:29:55
158
原创 回溯法---全排列
for循环遍历nums数组,区间为整个数组。如果nums[i]用过,则跳过本轮循环,否则,将used[i]设为true,代表使用了该元素,将nums[i]加入path中,递归数组中剩余的元素,回溯。当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。第一步:确定参数与返回值。参数为数组nums,无返回值。排列问题不需要startIndex,因为排列问题是有序的,每次都要从头开始遍历。思路:排列问题是有序的,需要一个used数组,标记已经选择的元素。
2024-08-03 22:18:35
157
原创 回溯法---非递减子序列
如果nums[i]<子序列最后一个元素,不符合题目要求,跳过此轮循环;其他情况都执行以下操作步骤:将nums[i]记录在哈希表中,将nums[i]记录到path中,递归遍历剩下的数组元素(树的深度),回溯。要记录树的每一个节点,且子序列至少有两个元素,所以当path.size()>1时,将path加入结果集。同一父节点的子节点数字不能重复,去重操作与之前的题目不同,本题不能重排数组,故需要用哈希表存储元素,避免重复。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
2024-08-03 22:00:40
271
原创 回溯法---子集(2)
第三步:确定单层递归逻辑。for循环遍历nums数组,区间为[startIndex,nums.length-1]。如果正在访问的值与前一个值相等,则跳过本轮循环;否则,将值加入path,递归数组剩下的值,回溯。第一步:确定参数与返回值。参数为数组nums,起始下标startIndex,无返回值。第二步:确定终止条件。当startIndex>=nums.length时,返回。,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。返回的解集中,子集可以按。思路:该题与子集那题相比只需多一个去重操作。
2024-08-01 16:32:00
141
原创 回溯法---子集
第三步:确定单层递归逻辑。for循环遍历nums数组,区间为[startIndex,nums.length-1]。将nums[i]加入path中,递归剩下的数组元素,回溯。第一步:确定参数与返回值。参数为数组nums,起始下标startIndex,无返回值。第二步:确定终止条件。当startIndex>=nums.length时,返回。思路:求子集的过程就相当于把树的所有节点记录下来。返回该数组所有可能的子集(幂集)。
2024-08-01 16:15:47
208
原创 回溯法---复原IP地址
第三步:确定单层递归逻辑。for循环遍历字符串s,区间为[startIndex,s.length()-1]。如果区间[startIndex,i]的字符串是合法的,则在下标i的后面加上分隔符,即分割好一段合法的段。更新pointNum,递归字符串剩下的部分,回溯。第一步:确定参数与返回值。参数为字符串s,起始下标startIndex,分隔符数量pointNum,无返回值。第二步:确定终止条件。当pointNum=3时,如果最后一段的字符串符合要求,则加入结果集。,用以表示一个 IP 地址,返回所有可能的。
2024-08-01 15:38:26
235
原创 回溯法---分割回文串
第三步:确定单层递归逻辑。for循环遍历s字符串,从startIndex到s.length()-1。如果[startIndex,i]的区间下标组成的字符串是回文串,则将该字符串加入path,否则跳过本轮循环。第二步:确定终止条件。当startIndex>=s.length(),说明找到了一组分割方案,将其加入结果集。第一步:确定参数与返回值。参数为字符串s,分割起始下标startIndex,无返回值。分割成一些子串,使每个子串都是回文串。题目:给你一个字符串。所有可能的分割方案。
2024-08-01 14:24:20
191
原创 回溯法---组合总和(2)
for循环遍历canditates数组,从startIndex到最后一个元素。剪枝优化在for循环条件中,当sum+canditates[i]>target时,结束循环。for循环中步骤:去重(canditates[i]=canditates[i-1]跳过本次循环),更新sum,更新path,递归调用,回溯。第一步:确定参数与返回值。参数为canditates数组,target,sum(path中元素之和),startIndex(遍历的起始下标),无返回值。思路:与上一题的区别就是需要增加去重操作。
2024-07-31 15:44:22
213
原创 回溯法---组合总和
for循环遍历candidates数组,从startIndex到candidates数组的最后一个元素。进行剪枝优化操作,当sum+candidates[i]>target时,就不必进行下去了。for循环里的步骤就是:更新sum,更新path,递归调用,回溯。参数为candidates数组,target,sum(path数组中现有值之和),startIndex(遍历的candidates数组下标起始),无返回值。如果至少一个数字的被选数量不同,则两种组合是不同的。对于给定的输入,保证和为。
2024-07-31 13:44:52
226
原创 回溯---电话号码的字母组合
第一步:确定参数与返回值。参数为digits(String类型的数字串),numString(String数组,对应每个数字映射的字母串),index(正在遍历的digits的下标,同时代表着树的深度),无返回值。第二步:确定终止条件。当index=digits.length()时,说明已遍历完一遍数组串,将结果加入结果集。第三步:确定单层遍历逻辑。for循环遍历digits中每个数字映射的字母串,将字母加入结果,递归,回溯。注意 1 不对应任何字母。的字符串,返回所有它能表示的字母组合。
2024-07-30 14:38:28
113
原创 回溯---组合总和(3)
不剪枝的情况下,for循环从startIndex到9进行遍历搜索组合,将值加入组合,递归,回溯。剪枝优化会有两处,一处是for循环从startIndex到9-(k-path.size())+1,一处是将值加入组合后,若sum>n,则直接回溯。第一步:确定参数与返回值。参数为n,k,startIndex(遍历起始值),sum(结果列表中数字之和),无返回值。当path.size()=k时,若sum=n则将该组合加入结果集,否则直接返回。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
2024-07-30 13:56:26
118
原创 回溯---组合
思路:组合问题是回溯思想的典型应用,其本质就是穷举,可以根据题目进行剪枝优化操作。回溯是递归的产物,因此使用回溯思想解决的问题一定用到了递归。使用递归,就要按照递归三部曲进行分析。for循环每次从startIndex开始,未剪枝时到n结束,进行剪枝优化到n-(k-path.size())+1结束。回溯法的搜索过程就是一个树形结构的遍历过程,for循环进行横向遍历,递归过程是纵向遍历。参数为n,k,startIndex(要遍历的数组的起始值)当结果中有k个数值时,将这个组合加入结果集,返回。
2024-07-30 12:51:33
226
原创 二叉树---把二叉搜索树转换为累加树
二叉搜索树的中序遍历为递增序列,该题结果是把这个递增序列的每一个值转换为该值到数组最后一个值的累加。如果从后往前加会更加方便,不用每次都扫一遍数组。这个思想转换到遍历二叉搜索树就等价于倒序的中序遍历,即右中左。树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点。的新值等于原树中大于或等于。
2024-07-28 13:51:37
179
原创 二叉树---将有序数组转换为平衡二叉搜索树
第三步:确定单层递归逻辑。将数组中间节点的值构造成一个新节点作为中节点,调用递归函数构造其左子树与右子树。思路:构造平衡二叉搜索树,尽可能左右子树的节点数相等,故不断地将数组进行二分即可。第一步:确定参数与返回值。参数为数组nums,起始下标left,终止下标right。第二步:确定终止条件。当left>=right时,没有元素可取了,返回null。排列,请你将其转换为一棵。题目:给你一个整数数组。
2024-07-27 13:24:27
210
原创 二叉树---修剪二叉搜索树
当节点值小于low时,递归遍历其右子树;当节点值大于high时,递归遍历其左子树。然后root.left承接其符合条件的左子树,root.right承接其符合条件的右子树。改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。参数为节点,low,high,返回值为节点。第二步:确定终止条件。通过修剪二叉搜索树,使得所有节点的值在。:与删除节点类似,使用递归法。给你二叉搜索树的根节点。
2024-07-27 12:55:17
158
原创 二叉树---删除二叉搜索树中的节点
情况五:要删除的节点有左孩子和右孩子,将左孩子移动到右孩子的最左节点的左孩子(代码解法),或者将右孩子移动到左孩子的最右节点的右孩子。对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。情况四:要删除的节点只有右孩子,右孩子成为根节点,返回root.right。情况三:要删除的节点只有左孩子,左孩子成为根节点,返回root.left。情况一:没有找到值为key的节点,遇到空节点,直接返回root。情况二:要删除的节点是叶子节点,直接删除,返回null。
2024-07-26 14:01:56
224
原创 二叉树---二叉搜索树中的插入操作
思路:找到空节点插入新节点,由于树是二叉搜索树,故需判断访问的节点值与插入值的大小决定递归访问左子树还是右子树。如果节点值>插入值,则递归遍历左子树;如果节点值<插入值,则递归遍历右子树。,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。遇到空节点,则创建新节点,即插入节点,并把插入节点返回。,将值插入二叉搜索树。返回插入后二叉搜索树的根节点。第一步:确定参数与返回值。参数为节点,插入值,返回值为树。,新值和原始二叉搜索树中的任意节点值都不同。给定二叉搜索树(BST)的根节点。
2024-07-26 13:20:05
116
原创 二叉树---二叉搜索树的最近公共祖先
中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(二叉搜索树是有序的。假设p的值>q的值,那么从上到下的遍历过程中第一次遇到的值在[p,q]区间中的节点就是二叉搜索树的最近公共祖先。给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
2024-07-25 16:33:37
110
原创 二叉树---二叉树的最近公共祖先
中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(当左孩子右孩子返回值都不为空时,说明p,q节点一个在左子树一个在右子树中,那么该中节点就是它们的最近公共祖先,返回中节点;当左孩子右孩子返回值有一个不为空时,说明p,q节点都在这个不为空的子树中,返回不为空的节点;当左孩子右孩子返回值都为空时,说明p,q节点还没有出现,返回Null。后序遍历,访问节点左孩子,访问节点右孩子,处理中节点。当节点为空时,返回节点;
2024-07-25 16:10:04
258
原创 二叉树---二叉搜索树中的众数
如果count>maxCount,说明resList结果集中存储的结果全都不符合要求,需要清除,把root.val加入结果集,maxCount需要更新为count;注意:返回值为int数组,结果集为List,将List转换为int数组不能直接调用toArray()函数,因为toArray()的返回值为Object数组。用pre存储前一个便利的节点,root为现在访问的节点 ,count存储现在访问的节点值出现的频率,maxCount存储节点值中最大出现频率,resList存储结果集。
2024-07-23 15:25:49
378
原创 二叉树---二叉搜索树的最小绝对差
思路:中序遍历二叉搜索树的顺序是递增序列,将该序列中的相邻值两两比较找到最小差值。差值是一个正数,其数值等于两值之差的绝对值。给你一个二叉搜索树的根节点。
2024-07-23 13:50:02
211
原创 二叉树---验证二叉搜索树
递归法,迭代法的中序遍历均可。需注意的是不能判断左节点<中节点<右节点就是二叉搜索树,而是左子树是二叉搜索树,右子树也是二叉搜索树,同时左节点<中节点<右节点才是二叉搜索树。思路:二叉搜索树的中序遍历结果是一个递增数组,可以根据这个性质来解题。,判断其是否是一个有效的二叉搜索树。给你一个二叉树的根节点。
2024-07-22 22:04:58
233
原创 二叉树---二叉搜索树中的搜索
第三步:确定单层递归逻辑。根据二叉搜索树的性质,比根节点小的节点在根节点的左子树,比根节点大的节点在根节点的右子树。若根节点的值>val,递归遍历左子树;若根节点的值<val,递归右子树。第二步:确定终止条件。如果root=null或者root.val=val时返回root。第一步:确定参数与返回值。参数为树节点root,整数值val,返回值为树节点。返回以该节点为根的子树。如果节点不存在,则返回。你需要在 BST 中找到节点值等于。给定二叉搜索树(BST)的根节点。
2024-07-22 10:34:40
165
原创 二叉树---合并二叉树
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;第一步:确定参数与返回值。参数为root1,root2,返回值为rootNew。第二步:确定终止条件。两棵树中任意一颗为空,则返回。第三步:确定单层递归逻辑。两节点之和赋给新节点。null 的节点将直接作为新二叉树的节点。返回合并后的二叉树。
2024-07-21 17:41:14
119
原创 二叉树---最大二叉树
第三步:确定单层递归逻辑。当endIndex-beginIndex=1,说明数组里只有一个元素,为该元素创建一个新节点;当endIndex-beginIndex>1时,遍历数组,找到最大元素的值与下标,创建节点root存储该元素,递归root.left与root.right。第一步:确定参数与返回值。参数为nums数组,要遍历区域的起始下标beginIndex,终止下标endIndex,区间左闭右开,返回值为树。当endIndex-beginIndex<1时,说明数组里无元素,返回null。
2024-07-21 16:26:31
222
原创 二叉树---从中序与后序遍历序列构造二叉树
第一步:确定参数与返回值。参数为中序数组,数组起始下标,终止下标,后序数组,数组起始下标,终止下标,返回值为树。3.找到后序遍历数组的最后一个元素在中序遍历数组中的位置,作为切割点。第二步:确定终止条件。4.切割中序数组,切割点前的值构成左子树,切割点后的值构成右子树。2.如果数组大小不为0,后序遍历数组的最后一个元素是树的根节点。5.切割后序数组,切成后序左数组,后序右数组。1.如果数组大小为0,说明为空节点。第三步:确定单层递归逻辑。6.递归处理左数组与右数组。是二叉树的中序遍历,
2024-07-20 15:10:01
156
原创 二叉树---路径总和
用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。如果遍历到了叶子节点,count不为0,就是没找到。因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。使用前序遍历,一个栈存放前序遍历的节点,一个栈存放根节点到该节点的值。参数为树节点,一个int类型的计数器,返回值为bool类型。是指没有子节点的节点。
2024-07-20 13:59:00
188
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人