登录社区云,与社区用户共同成长
邀请您加入社区
双指针循环枚举 `mid` 的每个位置,用 `j` 找最靠右的合法 `left`,用 `k` 找最靠左的合法 `right`,两者都是单调移动,总复杂度 O(N)。`s="aa", p="aa**"``2``left="aa"`, `mid=""`, `right=""`,匹配 `"aa"``s="madlogic", p="*adlogi*"``6`匹配 `"adlogi"`- 给定字符串 `s
本文介绍了一种使用滑动窗口和哈希表来寻找字符串中最长无重复字符子串的高效算法。该方法通过双指针维护一个动态窗口,左指针(left)控制窗口收缩,右指针(right)扩展窗口。哈希表记录字符最后一次出现的位置,当遇到重复字符时快速调整窗口边界。算法时间复杂度为O(n),空间复杂度为O(min(m,n))。关键点包括:1)滑动窗口技术优化了暴力解法;2)哈希表存储字符位置实现快速查询;3)正确处理边界
LeetCode 1848.到目标元素的最小距离:数组遍历(附python一行版)给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数 target 和 start ,请你找出一个下标 i ,满足 nums[i] == target 且 abs(i - start) 最小化 。注意:abs(x) 表示 x 的绝对值。返回 abs(i - start) 。题目数据保证 target
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。如果你已经完成今天的两个小练习恭喜你,已经达到练气四阶!你可以按任意顺序返回答案。整数,并返回它们的数组下标。,请你在该数组中找出。
本文介绍了5道栈相关的LeetCode题目及解法: 逆波兰表达式求值 - 使用栈存储操作数,遇到运算符时弹出栈顶两个元素运算后压回栈。 最小栈 - 用辅助栈同步记录当前最小值,保证常数时间获取最小值。 括号最大嵌套深度 - 遍历字符串,统计左括号数量并更新最大深度。 有效括号 - 栈匹配括号,遇到右括号检查栈顶是否对应左括号。 简化路径 - 按/分割路径,用栈处理..和.,最终拼接为标准路径。 核
本文总结了几道常见算法题的解题思路。对于整数各位积和之差(1281题),通过循环取余分解数字并计算积与和的差;判断2的幂(231题)和3的幂(326题)时,利用位运算或数学特性进行优化;丑数问题(263题)通过分解质因数解决;数组重排(1470题)和矩阵转置(867题)考察数组操作;字符串分割得分(1422题)和元音统计(2586题)处理字符串特性;山脉数组峰顶(852题)采用二分查找优化。这些题
这道题最巧妙的地方,就是把二维矩阵的全 1 子矩形问题,转化成了楼层柱状图问题。再利用题目可以重排列的条件,直接排序贪心求解,思路清晰、代码简洁,是一道非常经典的贪心与矩阵结合的好题。
nums[i], nums[j] = nums[j], nums[i]# 交换到正确位置。# 当前前缀和减去之前的最小前缀和,得到以当前位置结尾的最大子数组和。在遍历过程中,对于每个位置j,只需要找到之前最小的前缀和,就能得到以j结尾的最大子数组和。# 当当前数在[1, n]范围内,且不在正确位置上时,进行交换。# suf[i]表示nums[i+1]到nums[n-1]的乘积。子数组[i,j]的和
今天的题都是数组和链表相关的,看来之前做的效果不错,感觉都有思路,自己也基本都能敲出来。
双指针法是解决数组/链表问题的常用技巧,主要包括对向指针和快慢指针两种类型。典型应用场景包括原地修改数组(如移动零)、有序数组查找(如两数之和)和链表操作(如环形链表)。快慢指针通过fast遍历和slow记录实现原地修改,时间复杂度O(n),空间复杂度O(1)。对向指针从两端向中间逼近解决查找问题。核心技巧是根据题目特点选择合适的指针类型,通过单次遍历和覆盖/交换操作实现高效处理,避免使用额外空间
核心作用是:在遍历一个可迭代对象(如列表、元组、字符串等)时,同时获取元素的“索引(下标)”和“元素值”。中心扩展法,也就是:每一个回文串都有一个“中心”,从中心向左右两边扩展,只要左右字符相等,就继续扩展。哈希表是底层的“数据结构”,而字典是 Python 语言中基于哈希表实现的一种“高级抽象”。“哑巴节点”(Dummy Node),在算法中更常见的叫法是。(通常初始化为 0 或 null),它
下面都是用左闭右开区间来写的(因为我比较喜欢用左闭右开区间)
文章摘要:排序+双指针是解决三数之和问题的经典方法。首先对数组排序,然后固定基准元素,在右侧子数组中使用左右指针逼近。通过比较三数之和与目标值的关系移动指针,同时采用基准元素去重和结果元素去重技巧避免重复解。该方法时间复杂度为O(n²),远优于暴力解法的O(n³)。关键点包括:排序预处理、双指针移动策略、去重逻辑以及剪枝优化(当基准元素>0时提前终止)。该思路可推广至n数之和问题,具有通用性
摘要:本文详解LeetCode 138题"随机链表的复制"问题,提出两种解决方案:1)"拼接-赋值-拆分"三步法,通过$O(1)$空间复杂度实现深拷贝,巧妙利用节点位置关系解决random指针问题;2)递归+哈希表法,以$O(N)$空间换取更直观的逻辑。文章对比了两种方法的优缺点,强调迭代法适合空间敏感场景,而递归法代码更简洁。核心在于理解深拷贝的本质及链表
本文探讨了查找最长连续数字序列长度的问题。通过将数组转换为集合实现O(1)时间复杂度的存在性检查,算法仅从序列起点开始计数,避免重复计算。具体步骤为:遍历集合中的数字,当发现某数字的前驱不存在时,将其作为起点向后扩展,记录最长序列。该解法时间复杂度O(n),空间复杂度O(n),相比暴力解法显著优化。Python集合的高效查找特性是该算法的关键。
给定一个整数数组nums和一个整数目标值target,请你在该数组中找出target的那整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意顺序返回答案。
开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。注意,word2 比 word1 长,"rs" 需要追加到合并后字符串的末尾。注意,word1 比 word2 长,"cd" 需要追加到合并后字符串的末尾。所以使用字符串切片,将后续的字符串加入到新的变量new中。合并后:a p b qrs。合并后:a p b q cd。b.因为需要一直对
return 1+max(left_depth,right_depth)//最后加上root节点。left_depth=self.maxDepth(root.left)//算出左子树最深。right_depth=self.maxDepth(root.right)//算出右子树最深。1.可以使用递归 算法,算每个节点的左子树和右子树的深度(选择最大的),然后加上自己这一层,就可以知道最大深度。循环遍
有序二维矩阵整体二分的技巧:定义一个映射关系,对于一维索引,用整除列数得到行号,用取余列数得到列号。即:一维索引 index —> 二维行号 = index // n,二维列号 = index % n。有了这个映射,就可以直接对整个矩阵进行一次二分查找
因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。整数,并返回它们的数组下标。你可以按任意顺序返回答案。题目:给定一个整数数组。,请你在该数组中找出。
定义 `dp[(g1, g2)]` 为:处理完部分元素后,`seq1` 的 GCD 为 `g1`、`seq2` 的 GCD 为 `g2` 的方案数。其中 `g1=0` 或 `g2=0` 表示对应子序列为空。1. 放入 `seq1`:`g1` 更新为 `gcd(g1, num)`(若 `g1=0` 则变为 `num`)2. 放入 `seq2`:`g2` 更新为 `gcd(g2, num)`(若 `g
1. 单调性:如果一个子数组 `[i, j]` 可以在 `k` 次操作内变为非递减,那么它的所有子数组(如 `[i+1, j]`、`[i, j-1]` 等)也一定可以。2. 为什么从右往左?`nums = [6,3,1,2,4,4], k = 7``17`21 个子数组中 4 个不满足。`nums = [5,4,3,2,1], k = 100``15`k 足够大,全部满足。`nums = [1,2
摘要:本文介绍Python高效解题技巧与LeetCode238题解法。首先讲解Python实用工具:defaultdict自动初始化字典和float('inf')处理极值。针对"除自身以外数组乘积"问题,提出两种解法:1)左右乘积数组法(空间O(n)),通过预处理左右乘积求解;2)优化版(空间O(1)),复用输出数组动态计算。两种方法时间复杂度均为O(n)。最后指出这种左右分解
特殊情况判断完成之后,看当前元素和 l 位置元素 r 位置元素的和是否为0,是0的话直接将结果更新,并将 l r 重复的跳过,并更新 l r 的位置。如果大1值存在,需要不断循环判断更大的是否存在,知道序列的最大值。思路:使用python的dict,将排好序的字符串作为dict的key,将当前元素作为dict的value,其中value是列表类型。给一个整数数组,判断其中是否存在nums[i] +
回溯算法本质上就是一种暴力穷举,只是套上了一层递归的壳子。只要按照“回溯三部曲”的框架去思考,理清参数、终止条件和单层逻辑,再难的题目也能被拆解得明明白白。照例附上。
matrix[i][0] = 0# 标记第i行需要置零。matrix[0][j] = 0# 标记第j列需要置零。first_col_zero = False# 标记第一列是否需要置零。# 第一次遍历:用第一行和第一列记录需要置零的行和列。# 第二次遍历:根据标记置零(除第一行第一列外)利用矩阵的第一行和第一列作为标记位,记录对应行和列是否需要置零。两次遍历即可完成标记和修改,时间复杂度O(m×n)
对于 j >= 1:buy[0][j] = sell[0][j] = -∞(不可能完成 ≥1 笔交易)sell[i][j]:第 i 天结束后,已完成 j 笔交易且当前不持有股票 的最大利润。buy[i][j]:第 i 天结束后,已完成 j 笔交易且当前持有股票 的最大利润。状态设计buy[j] 和 sell[j] 表示完成 j 笔交易的状态。sell[j] 依赖 buy[j-1](前一天的状态)?
优化 Trie(前缀树)在查询效率上的表现,是提升自动补全、拼写检查、敏感词过滤、LeetCode 212 等应用性能的核心。以下是 系统性、分层次的优化策略,涵盖数据结构、算法、缓存和工程实践。TrieNode[26](数组)O(1)高(固定 26×指针)纯小写英文字母(如 LeetCode)✅。📌 Google 的 Double-Array Trie 是工业级实现(用于日文分词)现代 CPU
→ 前三高:Max (1), Joe & Randy (2), Janet (3) → 共 4 人 ✅。例如:[100, 90, 90, 80] → 排名 [1, 2, 2, 4] ❌(会漏掉第 3 名)– 例如:[100, 90, 90, 80] → rk=[1,2,2,4],80 被排除。使用 DENSE_RANK() 而不是 ROW_NUMBER() 或 RANK()例如:[100, 90,
压缩 Trie(也称为 Radix Tree、Patricia Trie 或 Compact Prefix Tree)是一种通过合并单子节点路径来减少节点数量和内存占用的 Trie 变体。通过合理应用这些技巧,压缩 Trie 可在保持 O(L) 查询时间的同时,减少 50%~90% 的内存占用,是高性能文本系统的基石之一。⚠️ 注意:children 应用 Trie 或排序 Map 加速匹配(否则
整套算法不以单一关键词检索为核心,而是围绕招投标全场景需求,对全网标讯数据进行全域采集、智能解析、精准匹配、风险筛选、趋势预判,自动从海量杂乱信息里,筛选、归类、推送与企业经营范围、资质等级、承接预算、业务区域高度契合的招标项目、拟在建工程、采购需求,彻底改变传统人工逐条翻阅、关键词硬搜找标的低效模式,实现从 “人找信息” 转向 “信息找人”。算法自动排除资质不符、预算过低、工期不合理、虚假招标、
【代码】DeepSeekLeetCode.2088统计农场中肥沃金字塔的数目 public int countPyramids(int[][] grid)
不可连续向下跳:在 a 次向上跳形成的 a+1 个间隙中,最多每个间隙放一次向下跳,所以 down ≤ a + 1。// 向上跳的总步数:1 + 2 + 4 + ... + 2^(a-1) = 2^a - 1。// 向下跳次数不能超过 a+1(因为 a 次向上跳后有 a+1 个空隙)1. 向上跳的规律:第 i 次向上跳 2^(i-1) 步,所以跳 a 次后总步数为 2^a - 1。2. 最终位置:
return y。
1. `need[i]` 的构建:`need[v] |= 1 << u` 表示节点 `u` 必须在 `v` 之前。转移条件 `(need[i] & mask) == need[i]` 等价于 `need[i]` 是 `mask` 的子集,即 `i` 的所有前驱都已处理。2. 位置计算:`pos = mask.bit_count() + 1`,因为 `mask` 中已有 `bit_count()`
2. 模运算拼接:拼接 `a` 和 `b` 的数学表示为 `a * 10^len(b) + b`。3. 状态压缩 DP:`dp[mask][mod]` 表示已选数字集合为 `mask`,当前拼接数模 `k` 为 `mod` 是否可行。1. 排序保证字典序:先对 `nums` 排序,在 DFS 和重建路径时都按升序尝试,这样第一个找到的可行解就是字典序最小的排列。3. 状态压缩:用 `mask`(二
【代码】codex重新连接5次的问题。
3. 若 `s1 < s2`,差值 `diff = s2 - s1`,检查下半部分是否存在值为 `diff` 的单元格,且移除后仍连通。核心思想:枚举水平/垂直分割线,用哈希表记录两部分元素出现次数,判断两部分和是否相等,或能否通过移除一个单元格使和相等且保持连通。差值计算`diff` 为两部分和的绝对差,只有较大一侧移除 `diff` 后才能使两部分和相等。1. 枚举水平分割线,逐行将元素从下半
例如 `[left..right]=[7,8,9,10,11]`,排列为 `9-11-10-8-7`,相邻乘积和最大。// 所有节点度数为2的连通分量(环)// 其余连通分量(链)处理顺序环优先于链,因为环的每个节点都有两条边,大数在环中能产生更多乘积;3. 填数策略——将剩余的最大数放在连通分量的中间,次大的数交替向两边扩展,使得大数尽量相邻(类似排序不等式)。1. 先处理环,再处理链——环的每
树上距离\text{dist}(u, v) = \text{dist}[u] + \text{dist}[v] - 2 \cdot \text{dist}[\text{lca}(u,v)]最终答案对每个查询,(\text{dist}(src1, src2) + \text{dist}(src1, dest) + \text{dist}(src2, dest)) // 2。倍增表`up[v][j]`
本文介绍了三种方法求解二进制数组中删除一个元素后最长连续1子数组长度的问题。第一种是滑动窗口法,通过维护窗口内0的数量不超过1来寻找最长子数组。第二种是对滑动窗口的优化,使用变量记录左边界位置。第三种是动态规划法,通过维护两个状态变量dp0和dp1分别表示未删除和已删除一个元素时的最长长度。三种方法的时间复杂度均为O(n),空间复杂度为O(1)。其中动态规划法通过状态转移规则优雅地处理了不同情况,
本文介绍了四道二叉树相关算法题的解法。112题通过递归减去节点值判断是否存在路径和等于目标值;513题使用深度优先搜索记录最底层最左节点值;106和105题分别根据中序+后序、前序+中序遍历序列重构二叉树,通过哈希表定位根节点并递归构建左右子树。所有解法均采用递归思想,通过巧妙处理遍历序列和节点位置关系来解决问题。
本文总结了三个二叉搜索树相关算法:700题通过递归在BST中搜索指定值节点;617题递归合并两棵二叉树,重叠节点值相加;98题利用中序遍历验证BST的有效性,检查节点值是否严格递增。三个问题都采用递归解法,分别处理了BST的查找、合并和验证操作,体现了递归在树结构问题中的典型应用模式。
一个机器人位于一个m x n网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?283从左上角开始,总共有 3 条路径可以到达右下角。1. 向右 -> 向下 -> 向下2. 向下 -> 向下 -> 向右3. 向下 -> 向右 -> 向下286。