自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(472)
  • 收藏
  • 关注

原创 2025年- H81-Lc189--279.完全平方数(动态规划)--Java版

(3)但是这道题中 ,物品之间是没有顺序的。最外层循环遍历 1 到 n,而内层循环遍历所有小于等于 j 的完全平方数(大约是 sqrt(j) 次)。因此,时间复杂度大约是 O(n * sqrt(n))。构建 dp 数组时,dp[0] = 0 的意思是:为了表示数字 0,我们不需要任何的平方数,这个是唯一的正确答案。(1)因为给的任何一个数,都可以用1去拼凑(1也是完全平方数),所以题目要求要用最少的完全平方数。(2)先遍历物品再遍历背包,求的是组合数。先遍历背包再遍历物品,求的是排列数。

2025-06-11 17:25:35 277

原创 2025年- H80-Lc188--198.打家劫舍(动态规划)--Java版

(4)如果偷最后一个房间,则收获的最大钱币数dp[i-2]+dp[i]。如果不偷最后一个房间,则收获的最大钱币数dp[i-1].(3)因为前两个元素已经初始化了,所以i从2开始遍历,遍历到最后一个元素nums.size()-1。(2)如果有两个房间的时候,dp[i]=math.max(nums[0],nums[i])。(1)首先只有一个房间的时候,dp[0]=nums[0].考虑头两个元素的状态,和最后一个元素的状态。

2025-06-11 16:25:28 174

原创 2025年- H79-Lc187--118. 杨辉三角(找规律)--Java版

其次从第三行开始,中间的数字等于前一行数字的和。首先第1个数字和末尾的数字都是1.

2025-06-10 00:14:27 310

原创 2025年- H78-Lc186--763.划分字符串区间(贪心)--Java版

(1)存储子串的索引和该字符出现的最远位置。

2025-06-08 11:17:17 206

原创 2025年- H77-Lc185--45.跳跃游戏II(贪心)--Java版

以最少的步数尽可能的增加覆盖范围,只要覆盖范围把最远的终点覆盖掉,就说明当前的步数可以跳到终点。每次尽可能往远一点跳,就能以最少的步数达到终点。每次只记录下一步的最大范围。

2025-06-07 16:43:41 289

原创 2025年- H76-Lc184--55.跳跃游戏(贪心)--Java版

全局最优:在这个序列里,可以得到最大的覆盖范围。如果覆盖范围能达到最后一个元素,就是全局最优。(1)数组的长度是1,一开始在起始位置,本质上也是在终止位置,所以可以返回true。局部最优:每遍历一个元素取它最大的覆盖范围。只要是在最大覆盖范围覆盖了,就是覆盖了。

2025-06-07 16:15:03 297

原创 2025年- H75-Lc183--121.买卖股票的最佳时机1(贪心or动态规划)--Java版

如果再第i天就把股票卖了,所以再i-1天股票是保存有的状态,dp[i][1]=dp[i-1][0]+prices[i]. 所以可以得到递推公式dp[i][1]=max(dp[i-1][1],dp[i-1][0]+price[i])求二者之间的最大值dp[i][0]=max(dp[i-1][0],-price[i])1)dp[i][0]:持有股票的最大现金(可能在i的前几天买了这个股票,第i天只是拥有持有股票的状态)最终结果在这两个数组中取一个最大值:dp[n-1][0],dp[n-1][1]取一个最大值。

2025-06-07 10:47:38 376

原创 2025年- H74-Lc182--79.单词搜索(回溯,组合)--Java版

给定一个二维字符网格和一个字符串 word,判断是否存在一条路径,通过相邻(上下左右)单元格拼出这个单词,每个单元格只能使用一次。对于二维布尔矩阵 visited,使用 boolean[][] 是最安全且高效的方式。,尽量使用基本类型 boolean 而不是 Boolean。

2025-06-07 00:38:26 278

原创 2025年- H73-Lc181--22.括号生成(回溯,组合)--Java版

(2)如果还没用完所有的左括号(open < n),就可以继续加左括号。递归调用:左括号数量加 1,继续构造。回溯关键步骤:撤销上一步加的括号,回到上一个状态,尝试其他组合。(1)终止条件:如果当前字符串长度为 2 * n,说明括号已经填满(n 个左括号和 n 个右括号),加入结果列表并返回。(3)如果当前右括号数量比左括号少(close < open),则可以加一个右括号。(4)new stringbuffer()是可变字符串长度。与左括号逻辑类似:加右括号 → 递归 → 撤销(回溯)。

2025-06-06 23:46:07 262

原创 2025年- H72-Lc180--131.分割回文串(回溯,回文,组合)--Java版

(1)确定递归函数和返回值类型(void)

2025-06-05 15:40:53 213

原创 2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

对象类型:可以调用 toString() 方法,将对象转为字符串。大多数 Java 内建类(如 String, List)已经重写了 toString() 方法来提供默认的字符串表示。原始类型:不能直接调用 toString(),但可以通过 Integer.toString(), String.valueOf() 等方法转换为字符串。补充: toString():当你需要将对象转换为字符串形式(例如将对象内容拼接到其它字符串中),你可以显式调用 toString()。当前的元素可以重复使用。

2025-06-05 15:16:14 332

原创 2025年- H70-Lc178--17.电话号码的组合(回溯,组合)--Java版

(2)排列强调元素之间的顺序,所以[1,2,6]和[2,6,1]代表不同的数。(1)组合不强调元素的顺序,所以[1,2,6]和[2,6,1]代表同一个数。(3)回溯通过递归的方式实现每一层的for循环,回溯算法可以抽象为树形结构。

2025-06-05 14:15:01 511

原创 2025年- H69-Lc177--78.子集(回溯,组合)--Java版

【代码】2025年- H69-Lc177--78.子集(回溯,组合)--Java版。

2025-06-05 00:01:30 215 1

原创 2025年- H68-Lc176--46.全排列(回溯,组合)--Java版

所以 cur.remove(2) 就是移除索引为 2 的元素,即移除 3,此时 cur 变成 [1, 2]。(1)终止条件:当path.size()==nums.size()说明要到收获的结果了(也就是叶子节点)。使用一个临时列表 cur 表示当前构造中的排列;每次递归遍历 nums 中还未使用的元素;达到终止条件后将 cur 加入结果集中;用回溯法(递归 + 回退)尝试所有可能。

2025-06-04 23:29:33 290 1

原创 2025年- H67-Lc175--295.数据流中的中位数(小根堆,大根堆)--Java版

queMin 存:[3, 2, 1] → 最大堆 → 堆顶是 3。queMax 存:[4, 5, 6] → 最小堆 → 堆顶是 4。中位数 = (3 + 4) / 2 = 3.5。

2025-06-04 14:51:26 154

原创 2025年- H66-Lc174--215.数组中的第k个最大元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版

【代码】2025年- H66-Lc174--215.数组中的第k个最大元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版。

2025-06-04 11:36:13 508

原创 2025年- H65-Lc173--347.前k个高频元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版

(1)这里定义了一个小根堆(最小堆),根据元素的频率从小到大排序。虽然 remove() 是按频率从小到大弹出,但我们关心的是内容是这 k 个元素本身是否是频率最高的。加入 2(频率2)→ pq = [2, 1](按频率排序,堆顶是频率最小的)(1)输入:nums = [1, 1, 1, 2, 2, 3],k = 2。加入 2,堆 = [1, 2](根据频率排序,2 的频率低,堆顶是 2)(2)频率统计结果:map = {1=3, 2=2, 3=1}现在 pq 中是 [2, 1],是频率前 2 高的元素!

2025-06-04 10:57:21 466

原创 2025年- H64-Lc172--153.寻找旋转排序数组中的最小值(查找)--Java版

【代码】2025年- H64-Lc172--153.寻找旋转排序数组中的最小值(查找)--Java版。

2025-06-03 16:11:33 163

原创 2025年- H63-Lc171--33.搜索旋转排序数组(2次二分查找,需二刷)--Java版

限制:时间复杂度为 O(log n),所以不能用遍历,必须使用 二分查找!二分查找:搜索区间必须是“单调有序”的(即 单调递增 或 单调递减)。输出:target 在 nums 中的下标,如果不存在,返回 -1。输入:旋转后的数组 nums,和一个整数 target。(1)首先翻转后的数组,构成两个有序数组。(2)对第一个有序数组进行二分查找。(3)对第二个有序数组进行二分查找。

2025-05-31 22:59:59 245

原创 2025年- H62-Lc170--34.在排序数组中查找元素的第一个和最后一个位置(2次二分查找,标记向左寻找,标记向右寻找)--Java版

【代码】2025年- H62-Lc170--34.在排序数组中查找元素的第一个和最后一个位置(二分查找)--Java版。

2025-05-31 22:08:02 291

原创 2025年- H61-Lc169--74.搜索二维矩阵(二分查找)--Java版

定义其实坐标,右上角的元素(0,n-1)。进入while循环(注意边界条件,行数小于m,列数要>=0)从右上角开始开始向左遍历(比当前元素target小的元素),向下遍历(比当前元素target大的元素),如果while循环结束都没找到,返回false。若将矩阵每一行拼接在上一行的末尾,则会得到一个升序数组,我们可以在该数组上二分找到目标元素。可以二分升序数组的下标,将其映射到原矩阵的行和列上。col = mid % 列数,表示这是该行中的第几个元素。row = mid / 列数,表示这是第几行;

2025-05-31 20:44:38 561

原创 2025年- H60-Lc168--35.搜索插入的位置(二分查找)--Java版

【代码】2025年- H60-Lc168--35.搜索插入的位置(二分查找)--Java版。

2025-05-30 17:22:57 221

原创 2025年- H59-Lc167--207.课程表(拓扑排序、BFS)-需二刷--Java版

(3)统计完每个节点的入度,使用广度优先搜索。因为入度为0,说明没有先修课程,也就是先修课程已经完成了。如果c1已经修完,C3和C8以C1为先修课程,所以入度就可以-1.(1)如果有向图中的拓扑图中存在环,则说明所有的课程是无法完成的。记录每门课程的前置课程数量,记录每门课程是哪些课程的前置课程。最后要判断优秀,已学习的课程的数量是否等于输入课程的数量。(2)使用拓扑排序,在图中每个节点的入度和出度。将入度为0的课程加入到待学习的课程中。

2025-05-30 15:59:52 270

原创 2025年- H58-Lc166--208.实现Tri(前缀树)(图论,广搜)--Java版

如果 searchPrefix(word) 返回的节点不为 null,并且 node.isEnd == true,说明这个单词完整存在于 Trie 中。如果是前缀但不是完整单词(即 isEnd == false),则返回 false。调用辅助方法 searchPrefix(String prefix)目的:找到这个 word 对应的最后一个字符所在的节点。如果遍历过程中某个字符没有对应的子节点,返回 null。检查返回的节点是否有效。

2025-05-30 11:02:01 181

原创 2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版

【代码】2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版。

2025-05-29 23:34:01 461

原创 2025年- H56-Lc164--200.岛屿数量(图论,深搜)--Java版

(3)辅助函数,用递归(深搜),遍历以已访问过的元素(陆地1)的相邻元素(陆地1)。(2)主函数,visit数组表示已访问过的元素。(1)主函数,存储图结构。(1)确定递归函数和参数。补充:深度搜索(递归)

2025-05-29 20:55:14 753

原创 2025年- H55-Lc163--124. 二叉树的最大路径和(深搜)--Java版

(1)至少要包含一个节点。所以就是以当前节点为根节点的左右孩子。(2)一个节点不能经过两次,子树(左右孩子)的和交给递归去做。递归过程,找到maxsum=max(maxsum,sum)递归返回结果:output=自己+max(左,右)递归公式:sum=自己+左+右。

2025-05-27 15:23:05 134

原创 2025年- H54-Lc162--437. 路径总和 III(递归[回溯]OR深搜)--Java版

求不同路径,用递归,当然递归里面包括前中后的遍历。我们采用前序遍历(根左右),从父节点到孩子节点。对每个节点作为起点,查找从它往下延伸的路径,是否有路径和等于 targetSum。外层 pathSum() 是遍历每一个节点(作为路径起点);内层 rootSum() 是从当前节点往下查路径和。

2025-05-27 14:30:32 204

原创 2025年- H53-Lc161--105. 从前序与中序遍历序列构造二叉树(分治)--Java版

2)而中序遍历的形式总是[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ].只要我们在中序遍历中定位到根节点,那么我们就可以分别知道左子树和右子树中的节点数目。这样以来,我们就知道了左子树的前序遍历和中序遍历结果,以及右子树的前序遍历和中序遍历结果,我们就可以递归地对构造出左子树和右子树,再将这两颗子树接到根节点的左右位置。(4)左子树的根节点在前序遍历中紧跟当前根节点的位置(root + 1),其在中序遍历中的范围是 [left, i-1]。

2025-05-27 11:03:41 1113

原创 2025年- H52-Lc160--114. 二叉树展开为链表(前序遍历 + 用栈 + 原地修改)--Java版

方法一:前序遍历 + 重构指针( no try)方法二:前序遍历 + 用栈 (yes try)(1)使用前序遍历 + 重构指针。(2)前序遍历 + 用栈。

2025-05-27 00:03:31 398

原创 2025年- H51-Lc159 --199. 二叉树的右视图(层序遍历,队列)--Java版

返回一个从右侧看二叉树时能看到的所有节点的值。右视图中的每一层只能看到最右边的节点。可以使用 层序遍历(BFS),每次遍历一层时,记录该层的最后一个节点的值。

2025-05-26 23:41:43 674

原创 2025年- H50-Lc158 --25. k个一组翻转链表(链表,双指针,虚拟头节点)--Java版

(5)特殊情况,当翻转部分长度不足 k 时,在定位 end 完成后,end==null,已经到达末尾,说明题目已完成,直接返回即可。(3)初始需要两个变量 pre 和 end,pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾。(4)经过k此循环,end 到达末尾,记录待翻转链表的后继 next = end.next。翻转链表,然后将三部分链表连接起来,然后重置 pre 和 end 指针,然后进入下一次循环。(2)需记录翻转链表前驱和后继,方便翻转完成后把已翻转部分和未翻转部分连接起来。

2025-05-25 16:48:13 269

原创 2025年- H49-Lc157 --230. 二叉搜索树中第k小的元素(前序+排序 OR中序)--Java版

二叉树的中序遍历即按照访问左子树——根结点——右子树的方式遍历二叉树;在访问其左子树和右子树时,我们也按照同样的方式遍历;先对二叉树进行一次完整遍历,将所有节点存入列表中,最后对列表排序后返回目标值。树的遍历可以使用 DFS 或 BFS。在二叉搜索树中,任意子节点都满足“左子节点 < 根节点 < 右子节点”的规则。所有左子树和右子树自身必须也是二叉搜索树。结点的左子树只包含小于当前结点的数。结点的右子树只包含大于当前结点的数。树的前序遍历 + 排序。方法二:(前序+排序)

2025-05-25 15:50:07 321

原创 2025年- H48-Lc156 --236. 二叉树的最近公共祖先(递归、深搜)--Java版

(1) 如果当前节点为 null,或者等于 p 或 q,直接返回。应该返回 root,因为找到了 p 或 q,不能返回 null。(4) 如果左右子树都找到了,说明 p 和 q 分别在左右子树中,当前节点是最近公共祖先。如果当前节点是 p 或 q,就返回它(因为从这里可以回溯寻找公共祖先)。如果当前节点 root 为 null,表示到达了叶子节点的空子树;(6)否则返回右子树的结果(可能是 null 或找到的节点)(2) 在左子树中查找 p 和 q。(3)在右子树中查找 p 和 q。

2025-05-25 14:53:41 174

原创 2025年- H47-Lc155 --102. 二叉树的层序遍历(队列、广搜)--Java版

(1)你可以不断往里面 .add(…) 数据,也可以用 .get(i) 访问特定位置的元素。它在遍历、存储树每一层的节点时非常好用。new ArrayList<>() 就是创建一个可以装元素的“动态袋子”。进了A分支就不会去B分支,去了B分支就不会去A分支。else if(B分支)(2)if(A分支)

2025-05-25 13:46:56 253

原创 2025年- H46-Lc154 --543. 二叉树的直径(深度、递归、深搜)--Java版

Depth() 返回的是深度(从当前节点到底部的边数),而不是节点数。如果你返回节点数,就要额外处理 -1。径定义为“路径经过的节点数 - 1”,而递归中我们实际是在统计“边数”。left + right 就已经是边数,无需再减 1。

2025-05-25 12:57:11 138

原创 2025年- H45-Lc153 --98. 验证二叉搜索树(树、递归)--Java版

如果将 pre 定义在 isValidBST 方法内部,它是一个 局部变量,在每次递归调用时都会重新初始化为 null,因此 中序遍历中的“前一个节点”状态无法保存,从而导致判断失效。所以要把pre设置成类的成员变量,这样才能在递归调用之间保持它的状态(即保存上一个访问的节点)。类的内部状态(像 pre 这种中间变量)一般应该被保护(private),避免外部代码直接修改,导致不可预测的错误。// 用于记录中序遍历中上一个节点。

2025-05-25 00:59:51 152

原创 2025年- H44-Lc152 --108. 将有序数组转换成二叉树(树、递归)--Java版

找到中间节点之后,根节点左边元素和右边元素都是闭区间。BST:二叉搜索树(Binary Search Tree)中序遍历,总是选择中间位置左边的数字作为根节点。

2025-05-25 00:33:21 147

原创 2025年- H43-Lc151 --101. 对称二叉树(递归)需二刷--Java版

1.如果根节点为空,则炜对称二叉树。5. 左右不为空,但是值不相等。6. 左右不为空,但是值相等。(1)外侧的值等于外侧。(2)内侧的值等于内测。2.左为空,右不为空。3.右有空,左不为空。

2025-05-23 16:35:10 191

原创 2025年- H42-Lc150 --146. LRU缓存(哈希表,双链表)需二刷--Java版

(2)put(),首先如果新加入的元素在哈希表中不存在,则直接创建新节点加入到map中。如果双向链表的节点数超过链表容量,则剔除尾部节点(包括它的值)。如果新加入的元素存在(key存在),我们通过get进行定位,把节点值进行更新,移动到头部(说明是最近刚被访问的)(3)get(),如果get(key)不存在直接返回-1,如果key存在,说明key节点是最近被使用的节点。通过哈希表定位到双向链表的位置,并将其移动到双向链表的头部,返回该节点的值。链表头部是最近刚使用过的元素,尾部是最近不经常使用的元素。

2025-05-22 15:47:55 599

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除