LeetCode 1282:用户分组,从相同容量分桶到满组即输出
相同组大小的人可以放在一起,但一个桶不一定就是一个组。用两个连续版本理解容量分组,并学会验证不唯一的答案。
相同组大小的人可以放在一起,但一个桶不一定就是一个组。用两个连续版本理解容量分组,并学会验证不唯一的答案。
题目要求 给定一个循环整数数组 nums,返回数组 answer。 对每个下标 i: answer[i] = 从 i 向右遇到的第一个严格大于 nums[i] 的元素值 如果绕行一圈后仍然没有更大元素,answer[i] = -1。 “循环数组”表示走过最后一个位置后,可以继续从下标 0 开始;但一个下标不能绕一圈后把自己当成答案。 LeetCode 提供的方法接口是: nextGreaterElements(nums: List[int]) -> List[int] 示例 1 输入:nums = [1,2,1] 输出:[2,-1,2] 第一个 1 向右首先遇到更大的 2。 2 绕行一圈也找不到严格更大的元素,答案是 -1。 最后一个 1 走到数组末尾后绕回开头,随后遇到 2。 示例 2 输入:nums = [2,2,2] 输出:[-1,-1,-1] 相等元素不属于“更大元素”。 示例 3 输入:nums = [7] 输出:[-1] 数组只有一个元素时,它不能把自己作为下一个更大元素。 约束 1 <= nums.length <= 10^4 -10^9 <= nums[i] <= 10^9 Step 1:循环数组中的“右边”到哪里结束 先看: ...
题目要求 给定一个非负整数数组 heights。每个 heights[i] 表示宽度为 1 的柱子高度,所有柱子紧挨排列。 题目要求返回柱状图中能够形成的最大矩形面积。 一个合法矩形必须覆盖一段连续柱子。它的宽度是这段区间包含的柱子数量,高度不能超过区间中的最矮柱。 LeetCode 提供的方法接口是: largestRectangleArea(heights: List[int]) -> int 示例 1 输入:heights = [2,1,5,6,2,3] 输出:10 下标 2 和 3 的两根柱子高度分别是 5 和 6,可以形成高度 5、宽度 2、面积 10 的矩形。 示例 2 输入:heights = [2,4] 输出:4 可以选择高度 4、宽度 1,也可以选择高度 2、宽度 2,最大面积都是 4。 约束 1 <= heights.length <= 10^5 0 <= heights[i] <= 10^4 Step 1:矩形面积不是柱高之和 先看一个小柱状图: heights = [2,1,2] 如果矩形覆盖全部三根柱子,它的宽度是 3,但高度最多只能是 1: height = 1 width = 3 area = 1 * 3 = 3 不能把三根柱高相加得到 5。柱状图矩形覆盖的是一块完整矩形区域,中间高度为 1 的柱子会限制整个区间的矩形高度。 ...
题目要求 给你一个非空整数数组 nums。 数组中只有一个元素出现一次,其余每个元素都恰好出现两次。题目要求返回那个只出现一次的元素。 LeetCode 提供的方法接口是: singleNumber(nums: List[int]) -> int 除了返回正确答案,解法还需要满足两个要求: 时间复杂度是 O(n)。 只使用 O(1) 额外空间。 示例 1 输入:nums = [2,2,1] 输出:1 2 出现两次,只有 1 出现一次。 示例 2 输入:nums = [4,1,2,1,2] 输出:4 1 和 2 都能找到相同的另一个元素,最后只有 4 没有配对。 示例 3 输入:nums = [1] 输出:1 数组只有一个元素时,它就是答案。 约束 1 <= nums.length <= 3 * 10^4 -3 * 10^4 <= nums[i] <= 3 * 10^4 除一个元素只出现一次外,其余元素都恰好出现两次。 Step 1:先把“只出现一次”说准确 先看: nums = [4,1,2,1,2] 在这个很小的数组里,我们可以用眼睛寻找相同的数字: ...
题目要求 给定一个整数数组 temperatures,其中 temperatures[i] 表示第 i 天的温度。 返回数组 answer,其中: answer[i] = 从第 i 天开始,需要等待多少天才会遇到更高温度 如果之后没有更高温度,answer[i] = 0。 这里的“更高”是严格大于。相同温度不能结算等待中的日期。 LeetCode 提供的方法接口是: dailyTemperatures(temperatures: List[int]) -> List[int] 示例 输入:temperatures = [73,74,75,71,69,72,76,73] 输出:[1,1,4,2,1,1,0,0] 约束 1 <= temperatures.length <= 10^5 30 <= temperatures[i] <= 100 Step 1:答案不是更高温度,而是等待天数 先看一个更小的输入: temperatures = [73,71,72,76] 逐天回答: 第 0 天是 73,右侧第一个更高温度是第 3 天的 76,等待 3 天。 第 1 天是 71,第 2 天的 72 更高,等待 1 天。 第 2 天是 72,第 3 天的 76 更高,等待 1 天。 第 3 天右侧没有日期,答案是 0。 所以结果是: ...
题目要求 给你一个整数数组 nums。 你一开始站在下标 0。 nums[i] 表示: 从下标 i 最多可以向右跳多少步 题目要求返回: 到达最后一个下标所需的最少跳跃次数 输入输出 输入:nums: List[int] 输出:int 从下标 0 出发 每个数字表示最大跳跃长度,不是必须跳这么远 题目保证一定可以到达最后一个下标 只需要返回最少跳数,不需要返回具体路径 示例 输入:nums = [2,3,1,1,4] 输出:2 一种最少跳法是: 0 -> 1 -> 4 从下标 0 跳到下标 1,再从下标 1 跳到最后一个下标。 输入:nums = [2,3,0,1,4] 输出:2 虽然中间有 0,但仍然可以: 0 -> 1 -> 4 约束 1 <= nums.length <= 10^4 0 <= nums[i] <= 1000 题目保证 nums[n - 1] 可达 Step 1:45 不是问能不能到,而是问最少几步到 如果刚做完 LeetCode 55,已经知道可以维护: ...
题目要求 给你一个数组 prices,其中 prices[i] 表示第 i 天的股票价格。 你只能完成一次交易: 选择某一天买入一支股票 选择未来某一天卖出这支股票 返回能获得的最大利润。如果无法盈利,返回 0。 输入输出 输入:prices: List[int] 输出:最大利润 int 只能买一次、卖一次。 买入日必须早于卖出日。 可以选择不交易,此时利润是 0。 示例 输入:prices = [7,1,5,3,6,4] 输出:5 最优做法是在价格为 1 时买入,在价格为 6 时卖出,利润是 6 - 1 = 5。 输入:prices = [7,6,4,3,1] 输出:0 价格一直下降,任何买入后再卖出都会亏钱,所以返回 0。 约束 1 <= prices.length <= 10^5 0 <= prices[i] <= 10^4 Step 1:先固定买卖顺序 先看这个例子: prices = [7,1,5,3,6,4] 如果只看价格差,最大利润来自: 1 -> 6 profit = 5 这是合法的,因为价格 1 出现在价格 6 之前。 ...
题目要求 给你一个整数数组 nums。 你一开始站在下标 0。nums[i] 表示从位置 i 最多可以向右跳多少步。 题目要求判断:能不能到达最后一个下标。 输入输出 输入:nums: List[int] 输出:bool 从下标 0 出发。 每个位置的数字表示最大跳跃长度,不是必须跳这么远。 只需要判断能否到达最后一个下标,不需要返回具体路径。 示例 输入:nums = [2,3,1,1,4] 输出:true 一种跳法是: 0 -> 1 -> 4 从下标 0 可以跳到下标 1,再从下标 1 跳到最后一个下标。 输入:nums = [3,2,1,0,4] 输出:false 无论怎么跳,都会被下标 3 的 0 卡住,无法到达最后一个下标 4。 约束 1 <= nums.length <= 10^4 0 <= nums[i] <= 10^5 Step 1:不要先猜路径,先看覆盖范围 先看失败样例: nums = [3,2,1,0,4] 从下标 0 最多可以跳到下标 3。 看起来选择很多: 0 -> 1 0 -> 2 0 -> 3 当前 baseline 是: ...
副标题 / 摘要 “顺时针螺旋遍历”看似只是打印顺序,实则考验你对边界与循环不变量的掌控。本文用 ACERS 结构给出可直接复用的边界收缩模板,并给出多语言可运行实现。 预计阅读时长:12~15 分钟 标签:Hot100、矩阵、模拟、边界收缩 SEO 关键词:Hot100, Spiral Matrix, 螺旋矩阵, 顺时针螺旋遍历, 边界收缩, LeetCode 54 元描述:用边界收缩法输出矩阵的顺时针螺旋序列,包含推导、工程场景、复杂度对比与多语言代码。 目标读者 正在刷 Hot100、想把“矩阵模拟题”沉淀成模板的同学 对边界条件容易写错、希望提升代码稳健性的中级开发者 做可视化/栅格数据处理/网格路径相关任务的工程师 背景 / 动机 矩阵类题目最容易“写得出来,但写不对”: 多一层循环、多一个边界判断,就可能在单行/单列、奇偶层数时出错或重复输出。 螺旋遍历是一个很好的训练题:它逼你把 循环不变量(哪些行列还没被处理)和 边界收缩(每处理完一条边就把边界往里缩)描述清楚,代码才能既短又不炸。 核心概念 边界(Boundaries):用 top/bottom/left/right 表示当前还未处理的矩形外框 层(Layer):每次循环处理一圈外框(上边、右边、下边、左边) 收缩(Shrink):每处理完一条边就移动对应边界:top++、right--、bottom--、left++ 循环不变量:始终保证未输出区域是 top..bottom × left..right A — Algorithm(题目与算法) 题目还原 给你一个 m 行 n 列的矩阵 matrix,请按照 顺时针螺旋顺序,返回矩阵中的所有元素。 输入输出 名称 类型 描述 matrix int[][] m × n 的矩阵 返回 int[] 按顺时针螺旋顺序输出的所有元素 示例 1(自拟) matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] 输出: [1, 2, 3, 6, 9, 8, 7, 4, 5] 示例 2(自拟) matrix = [ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12] ] 输出: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7] C — Concepts(核心思想) 思路推导:从“标记访问”到“边界收缩” 朴素思路:方向数组 + visited 标记 从 (0,0) 出发按右/下/左/上转向;走到越界或已访问就转向。 优点:直观 缺点:需要 m×n 的 visited,空间浪费;代码更容易写出越界/重复判断 关键观察:螺旋遍历 = 一圈圈“剥洋葱” 每一圈只需要处理四条边:上边一行、右边一列、下边一行、左边一列。 处理完外圈,就把边界往里缩,问题规模变小。 方法选择:边界收缩(O(1) 额外空间) 用四个指针维护未处理矩形:top, bottom, left, right。 每轮输出四条边(注意边界交叉时跳过),直到 top > bottom 或 left > right。 ...
副标题 / 摘要 “矩阵置零”是典型的二维标记传播问题:某个位置为 0,会影响整行整列。本文用 ACERS 结构讲清楚为什么不能直接改、如何用首行首列做标记实现原地 O(1) 额外空间,并给出多语言可运行代码。 预计阅读时长:12~15 分钟 标签:矩阵、原地算法、标记位 SEO 关键词:矩阵置零, 原地 O(1) 空间, 首行首列标记, LeetCode 73 元描述:用首行首列作标记位,原地将含 0 的行与列全部置零;包含推导、复杂度对比、工程迁移与多语言实现。 目标读者 刷 LeetCode,想把“二维数组原地技巧”沉淀成稳定模板的同学 需要在工程里做二维网格/表格/矩阵数据清洗与传播标记的开发者 对空间优化敏感(嵌入式、性能场景、内存受限)的工程师 背景 / 动机 二维数据在工程里到处都是:表格、图像、传感器网格、关联矩阵…… “某个单元格触发规则 -> 影响整行整列”这种联动,本质就是 行列传播(row/col propagation)。 这题额外要求“原地”,逼你掌握一个非常通用的技巧:用数据结构本身的某些位置当作标记位,避免额外内存。 核心概念 传播标记:发现 0 后,不是立刻改整行整列,而是先记录“哪些行/列要被清零” 原地(in-place):只允许 O(1) 额外空间(不算输入矩阵本身) 标记位复用:把 matrix[0][j] 当作“第 j 列要清零”的标记,把 matrix[i][0] 当作“第 i 行要清零”的标记 首行/首列特判:首行/首列既是数据又是标记位,因此需要单独用两个布尔量记录它们是否本来就该清零 A — Algorithm(题目与算法) 题目还原 给定一个 m x n 矩阵 matrix:如果某个元素为 0,则将该元素所在的 整行 与 整列 的所有元素都设置为 0。 要求 原地修改 matrix(通常不需要返回值)。 ...