- 博客(493)
- 收藏
- 关注
原创 CT02-20.有效的括号(Java)
这一行代码本身既可能返回 true 也可能返回 false,具体取决于在程序执行到这一步时,栈里是否还有剩余的元素。(1)判断此时栈是否为空,如果为空,说明没有左括号与右括号匹配,返回false。1)如果此时字符是‘)’,并且栈顶元素不等于‘(’,返回false。1)如果此时字符是‘]’,并且栈顶元素不等于‘[’,返回false。1)如果此时字符是‘}’,并且栈顶元素不等于‘{’,返回false。如果栈为空,说明所有的左括号都找到了匹配的右括号。先把字符串转换成字符数组。如果遇到左括号,入栈。
2025-08-22 00:02:54
106
原创 2025年- H99-Lc207--32.最长有效括号(栈、动态规划)--Java版
任何一个有效的括号字符串,其长度必然是偶数。比如 () 长度是2,(()) 长度是4,()() 长度也是4。一个长度为奇数的括号字符串(如 (、()))永远不可能是有效的。把(压入栈中,并且把(放入栈顶。在遍历过程中遇到的每个),我们从栈顶弹出(,如果栈顶没有(,或者遍历完整个字符串栈中仍有元素,那么该字符串是无效的。长度为2的子串:比如 ()。这是我们能找到的最短的、可能有效的括号组合。长度为1的子串:比如 ( 或者 )。它们不可能是有效的,因为无法配对。子串的长度是 j - i。
2025-08-19 21:35:50
233
原创 2025年- H98-Lc206--51.N皇后(回溯)--Java版
3)不能说45度或135度(斜对角线不能出现2个皇后)1)不能同行(同一行不能出现2个皇后)2)不能同列(同一列不能出现2个皇后)n代表树高,也就是嵌套for循环的行数。
2025-08-18 23:25:56
147
原创 2025年- H97-Lc205--23.合并k个升序链表(链表、小根堆、优先队列)--Java版
如果有n个链表,每次遍历k个节点,时间复杂度就是O(nk),k个节点的优化就是采用小根堆。用小根堆存储k个节点,每次弹出堆顶元素,下一个节点加入堆中,加入的时间复杂度是O(logK)分别使用两个指针,指向2个链表的头结点,每次取出值较小的节点,并把对应的指针后移,直到2个链表便利完成。初始4个指针都指向每个链表头结点,每次遍历这4个节点,找到最小的那个节点加入到结果,然后对应指针后移。同时把节点插入到当起啊指针的下一个节点,当前指针后移。(5)如果当前节点存在下一个节点,把它插入到堆中。
2025-08-17 17:54:22
137
原创 2025年- H96-Lc204--76.最小覆盖子串(子串、滑动窗口)--Java版
每次循环进行3个操作,把当前字符加入到窗口中,如果加到hs中的字符没有超过ht中字符的数量说明是有效字符,所以cnt+1。因为在窗口加入了新的字符,所以窗口左侧中会存在冗余字符所以要删,所以要右移窗口的左边界。如果cnt的数值等于ht的长度,说明已经窗口已经覆盖t的所有字符串.当前hs窗口字符A超过了ht所需要的A的元素的个数,所以j向后移动。滑动窗口,用两个哈希表来记录当前t中字符的数量和滑动窗口的数量。cnt:代表窗口滑动时的有效字符的数量。窗口滑动的同时要记录有效字符的数量。时间复杂度是O(n)
2025-08-17 16:50:19
166
原创 2025年- H95-Lc203-- 4.寻找两个正序数组的中位数(二分查找)--Java版
1)因为2个数组是有序数组,在同一个数组内,分割线一定满足左边的所有元素小于等于右边的所有元素。2)分割线在第1个数组右边的第1个元素的下标i=分割线在第1个数组左边的元素个数。分割线在第2个数组右边的第1个元素的下标j=分割线在第2个数组左边元素个数。如果总的元素个数为奇数,那边红色分割线左边的元素可以比右边元素的个数多1.如果总的元素个数为偶数,那边红色分割线的左右两边的元素个数要想等。(1)快速排序和归并排序的时间复杂度都是o(nlogN)红线左边的所有元素的数组小于等于红色右边所有元素的数值。
2025-08-17 14:59:15
188
原创 CT01-反转链表(Java)
定义一个next指针,存储临时变量(用于cur的后移操作)先设置一个pre指针和cur指针。然后pre和cur指针后移。pre指针指向NULL。cur指针指向头结点。
2025-08-17 12:32:12
124
原创 2025年- H94-Lc202-- 31.下一个排列(技巧)--Java版
比如初始数组是[1,2,3],所以对于第一个位置有3种可能,对于第二个位置有2种可能,最后一个位置有1种可能,所以总共有3*2=6种。给定一个整数数组 nums,找出它的下一个字典序排列(即比当前排列“刚好大一点”的排列)。如果不存在下一个排列(即已是最大排列),则返回最小排列(升序排列)。但是要求按字典序大小,查找下一个排列的数。(3)然后把后面升序排列(让它变最小)(2)在后面找一个刚比它大的数交换。(1)找从右往左第一个变大的地方。
2025-07-05 23:19:19
239
原创 2025年- H93-Lc201-- 64.最小路径和(多维动态规划)--Java版
dp[i][j]=dp[i-1][j]+1,1代表加了删除的操作才变成dp[i][j]dp[i][j]=dp[i][j-1]+1,1代表加了删除的操作才变成dp[i][j]dp[i][j]以i-1的word1字符串和j-1的word2字符串的最少操作次数。此时的字符串是不需要操作,i-2和j-2的操作次数与(i-1和j-1)的操作次数相等。2)word1[i-1]和word2[i-1]不相等的情况。1)word1[i-1]和word2[j-1]相等的情况。删除和添加是互逆的,操作步数是一样的。
2025-07-05 22:41:41
297
原创 2025年- H92-Lc200-- 64.最小路径和(多维动态规划)--Java版
(3)初始化,从起点到起点的路径和(只有这一个格子),要“消耗”这个格子的值了,所以路径和初始就是 1。必须从上到下、从左到右,因为 dp[i][j] 依赖于 dp[i-1][j] 和 dp[i][j-1]。(1)dp[i][j] 表示从起点 (0,0) 走到位置 (i,j) 的最小路径和。当前格子总路径和 = 当前格子的值 + 从上或左走过来的最小路径和。起点:dp[0][0] = grid[0][0]
2025-07-05 21:02:14
266
原创 2025年- H91-Lc199-- 62.不同路径(多维动态规划)--Java版
dp数组的遍历顺序:我们需要从左往右遍历,从上往下遍历。并且把第一行和第一列初始化为1,dp[i][0]=1,dp[0][j]=1。递推公式:dp[i][j]=dp[i-1][j]+dp[i][j-1]dp数组初始化,我们要确保第一行和第一列是有值的.//有 n 行(行索引从 0 到 n - 1)//有 m 列(列索引从 0 到 m - 1)所以最后一个格子是dp[n-1][m-1]dp含义:代表到当前位置的路径数。
2025-07-05 20:35:27
151
原创 2025年- H90-Lc198-- 1143. 最长公共子序列(多维动态规划)--Java版
【代码】2025年- H90-Lc198-- 1143. 最长公共子序列(多维动态规划)--Java版。
2025-07-05 19:00:44
248
原创 2025年- H89-Lc197-- 5. 最长回文子串(多维动态规划)--Java版
在前一轮 i=3 的时候,已经计算过 dp[2] = true(因为 “cc” 是回文)→ 所以 dp[1] = dp[2] = true,说明 “bccb” 是回文 ✅。3] = “cc” 是不是回文 → dp[2] = true。s[1] = ‘b’, s[4] = ‘b’ → 相等 ✅。4] = “bccb” 是不是回文。给你一个字符串 s,找到 s 中最长的 回文 子串。解释:“aba” 同样是符合题意的答案。输入:s = “abccba”输入:s = “babad”输入:s = “cbbd”
2025-06-23 21:02:34
130
原创 2025年- H88-Lc196--416.分割等和子集(动态规划)--Java版
我们想知道:dp[1][6] 是不是 true,也就是能否用前两个数 1 和 5 组成 6。所以状态是否成立就取决于之前用前 i 个数是否能组成 3(dp[i-1][3])dp 动态规划表,dp[i][j] 表示前 i+1 个数是否能组成和 j。→ 所以 dp[1][6] = false || true = true。dp[0][6] = false (只用 1 不能组成 6)dp[0][1] = true (只用 1 可以组成 1)考虑:i = 1,即当前数是 nums[1] = 5。
2025-06-23 20:04:28
279
原创 2025年- H87-Lc195--287.寻找重复数(技巧,二分查找OR动态规划)--Java版
【代码】2025年- H87-Lc195--287.寻找重复数(技巧,二分查找OR动态规划)--Java版。
2025-06-22 20:08:07
227
原创 2025年- H86-Lc194--152.乘积最大的数组(动态规划,累乘,遇到负数,交换当前的最大和最小值)--Java版
【代码】2025年- H86-Lc194--152.乘积最大的数组(动态规划,累乘,遇到负数,交换当前的最大和最小值)--Java版。
2025-06-22 16:56:42
204
原创 2025年- H85-Lc193--300.最长递增子序列(动态规划)--Java版
当前i指向的数,与i’之前的元素(用j表示)进行比较,如果当前的数大,开始更新dp[i]的值。dp[i]代表到达i元素的最长递增子序列的长度。
2025-06-22 15:42:44
167
原创 2025年- H84-Lc192--75.颜色分类(技巧、三路指针排序)--Java版
【代码】2025年- H84-Lc192--75.颜色分类(技巧、三路指针排序)--Java版。
2025-06-22 14:54:39
156
原创 2025年- H83-Lc191--139.单词拆分(动态规划)--Java版
字符串s是一个容器(一个背包),wordDict词典是物品,这里面的每个物品我们可以使用多次。dp[i] 表示 前 i 个字符(即下标 0 ~ i‑1 的子串)能否被字典单词完全拆分。(2)对于装满物品的背包是有顺序要求的。所以就是求排列数,我们需要先遍历背包再遍历物品。对每个终点 i (1 …n),枚举所有可能的切分点 j (0 …dp[0] = true:空串视为可拆分的起点。(1)字符串的长度为i,dp[i]=true。dp[0]=代表空字符串。
2025-06-22 00:10:20
459
原创 2025年- H82-Lc190--322.零钱兑换(动态规划)--Java版
(2)装满容量为j,最少的物品为dp[j],要求硬币数量dp[amount]装满这个背包(总金额)要用多少容量(硬币数量)。(4)不管是排列还是组合,这道题都是要装满背包。for(物品) for(背包)-》组合数。for(背包)for(物品)-》排列数。这里面钱币的数量是无限的。(1)确定dp数组的含义。
2025-06-17 23:41:44
298
原创 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
441
原创 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
211
原创 2025年- H79-Lc187--118. 杨辉三角(找规律)--Java版
其次从第三行开始,中间的数字等于前一行数字的和。首先第1个数字和末尾的数字都是1.
2025-06-10 00:14:27
326
原创 2025年- H77-Lc185--45.跳跃游戏II(贪心)--Java版
以最少的步数尽可能的增加覆盖范围,只要覆盖范围把最远的终点覆盖掉,就说明当前的步数可以跳到终点。每次尽可能往远一点跳,就能以最少的步数达到终点。每次只记录下一步的最大范围。
2025-06-07 16:43:41
302
原创 2025年- H76-Lc184--55.跳跃游戏(贪心)--Java版
全局最优:在这个序列里,可以得到最大的覆盖范围。如果覆盖范围能达到最后一个元素,就是全局最优。(1)数组的长度是1,一开始在起始位置,本质上也是在终止位置,所以可以返回true。局部最优:每遍历一个元素取它最大的覆盖范围。只要是在最大覆盖范围覆盖了,就是覆盖了。
2025-06-07 16:15:03
302
原创 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
390
原创 2025年- H74-Lc182--79.单词搜索(回溯,组合)--Java版
给定一个二维字符网格和一个字符串 word,判断是否存在一条路径,通过相邻(上下左右)单元格拼出这个单词,每个单元格只能使用一次。对于二维布尔矩阵 visited,使用 boolean[][] 是最安全且高效的方式。,尽量使用基本类型 boolean 而不是 Boolean。
2025-06-07 00:38:26
292
原创 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
290
原创 2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
对象类型:可以调用 toString() 方法,将对象转为字符串。大多数 Java 内建类(如 String, List)已经重写了 toString() 方法来提供默认的字符串表示。原始类型:不能直接调用 toString(),但可以通过 Integer.toString(), String.valueOf() 等方法转换为字符串。补充: toString():当你需要将对象转换为字符串形式(例如将对象内容拼接到其它字符串中),你可以显式调用 toString()。当前的元素可以重复使用。
2025-06-05 15:16:14
342
原创 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
528
原创 2025年- H69-Lc177--78.子集(回溯,组合)--Java版
【代码】2025年- H69-Lc177--78.子集(回溯,组合)--Java版。
2025-06-05 00:01:30
225
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
305
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
161
原创 2025年- H66-Lc174--215.数组中的第k个最大元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版
【代码】2025年- H66-Lc174--215.数组中的第k个最大元素(小根堆,堆顶元素是当前堆元素里面最小的)--Java版。
2025-06-04 11:36:13
516
原创 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
488
原创 2025年- H64-Lc172--153.寻找旋转排序数组中的最小值(查找)--Java版
【代码】2025年- H64-Lc172--153.寻找旋转排序数组中的最小值(查找)--Java版。
2025-06-03 16:11:33
172
原创 2025年- H63-Lc171--33.搜索旋转排序数组(2次二分查找,需二刷)--Java版
限制:时间复杂度为 O(log n),所以不能用遍历,必须使用 二分查找!二分查找:搜索区间必须是“单调有序”的(即 单调递增 或 单调递减)。输出:target 在 nums 中的下标,如果不存在,返回 -1。输入:旋转后的数组 nums,和一个整数 target。(1)首先翻转后的数组,构成两个有序数组。(2)对第一个有序数组进行二分查找。(3)对第二个有序数组进行二分查找。
2025-05-31 22:59:59
255
原创 2025年- H62-Lc170--34.在排序数组中查找元素的第一个和最后一个位置(2次二分查找,标记向左寻找,标记向右寻找)--Java版
【代码】2025年- H62-Lc170--34.在排序数组中查找元素的第一个和最后一个位置(二分查找)--Java版。
2025-05-31 22:08:02
313
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人