LeetCode78 - 跳跃游戏
📝 题目描述 题目链接:跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false。 示例: 1234567891011示例 1:输入:nums = [2,3,1,1,4]输出:true解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。示例 2:输入:nums = [3,2,1,0,4]输出:false解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。 提示: 1 <= nums.length <= 10^4 0 <= nums[i] <= 10^5 💡 解题思路 方法一:贪心算法 刚看到本题一开始可能想:当前位置元素如果是 3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢? 其实跳几步无所谓,关键在于可跳的覆盖范围!不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是...
LeetCode77 - 买卖股票的最佳时机
📝 题目描述 题目链接:买卖股票的最佳时机 给定一个数组 prices,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0。 示例: 123456789101112示例 1:输入:[7,1,5,3,6,4]输出:5解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。示例 2:输入:prices = [7,6,4,3,1]输出:0解释:在这种情况下, 没有交易完成, 所以最大利润为 0。 提示: 1 <= prices.length <= 10^5 0 <= prices[i] <= 10^4 💡 解题思路 方法一:贪心算法 假设给定的数组为:[7, 1, 5,...
LeetCode76 - 数据流的中位数
📝 题目描述 题目链接:数据流的中位数 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 例如 arr = [2,3,4] 的中位数是 3 。 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 MedianFinder 对象。 void addNum(int num) 将数据流中的整数 num 添加到数据结构中。 double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10−510^{-5}10−5 以内的答案将被接受。 示例: 12345678910111213输入["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"][[], [1], [2], [], [3], []]输...
多头注意力机制MHA
结合底部的测试用例(batch_size=2, seq_len=10, model_dim=64, num_heads=8),逐步跟踪数据在每个阶段的维度变化和计算逻辑。 零、初始化阶段(__init__) 1self.head_dim = model_dim // num_heads # 64 // 8 = 8 每个头的维度 dhead = 8。然后创建四个线性投影层: 1234self.w_q = nn.Linear(64, 64) # Wᵠ ∈ ℝ^(64×64)self.w_k = nn.Linear(64, 64) # Wᴷ ∈ ℝ^(64×64)self.w_v = nn.Linear(64, 64) # Wⱽ ∈ ℝ^(64×64)self.w_o = nn.Linear(64, 64) # Wᴼ ∈ ℝ^(64×64) 注意这里每个投影层的维度是 (model_dim, model_dim) = (64, 64),而不是 (64, 8)。这是因为所有头的投影被合并在一个大矩阵里,后面通过 reshape 来拆分成多个头。这样做的好处是只需要一次矩...
LeetCode75 - 前 K 个高频元素
📝 题目描述 题目链接:前 K 个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例: 1234567891011121314151617示例 1:输入:nums = [1,1,1,2,2,3], k = 2输出:[1,2]示例 2:输入:nums = [1], k = 1输出:[1]示例 3:输入:nums = [1,2,1,2,1,2,3,1,3,2], k = 2输出:[1,2] 提示: 1 <= nums.length <= 10^5 -10^4 <= nums[i] <= 10^4 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 💡 解题思路 方法一:桶排序 在长度为 N 的数组中,任何一个元素出现的频率(次数),最少是 1 次,最多也就是 N 次。 既然频率的范围被严格限制在了 [1,N][1,N][1,N] 这个有限的区间内,我们就不需要通过“比较”来排序(比如堆排序或快排),而...
LeetCode74 - 数组中的第K个最大元素
📝 题目描述 题目链接:数组中的第K个最大元素 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n)O(n)O(n) 的算法解决此问题。 示例: 123456789示例 1:输入: [3,2,1,5,6,4], k = 2输出: 5示例 2:输入: [3,2,3,1,2,4,5,5,6], k = 4输出: 4 提示: 1 <= k <= nums.length <= 10^5 -10^4 <= nums[i] <= 10^4 💡 解题思路 方法一:快速选择算法 利用了快速排序(Quick Sort)的 partition(划分)思想。 思路: 随机选择一个基准元素(pivot),将数组划分为两部分:左边的元素都大于 pivot,右边的元素都小于 pivot(降序划分)。 划分结束后,pivot 会落在一个确定的索引 p 上。 比较 p 和目标索引 k - 1: 如果 p == k - 1...
LeetCode73 - 柱状图中最大的矩形
📝 题目描述 题目链接:柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例: 示例 1: 123输入:heights = [2,1,5,6,2,3]输出:10解释:最大的矩形为图中红色区域,面积为 10 示例 2: 12输入: heights = [2,4]输出: 4 提示: 1 <= heights.length <=10^5 0 <= heights[i] <= 10^4 💡 解题思路 方法一:单调栈 这个题跟接雨水比较相像,接雨水要找出一个柱子左右两边第一个大于该柱子高度的柱子,本题是找每个柱子左右两边第一个小于该柱子的柱子。 本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序。 为了不再判断特例,可以设置两个哨兵节点,也就是高度为 0 的柱子到题目数组的两边,以便于我们及时将所有元素出栈。 维护一个非严格单调递增栈: 栈非空且当前遍历到的元素 heights[i] ...
LeetCode72 - 每日温度
📝 题目描述 题目链接:每日温度 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。 示例: 1234567891011121314示例 1:输入: temperatures = [73,74,75,71,69,72,76,73]输出: [1,1,4,2,1,1,0,0]示例 2:输入: temperatures = [30,40,50,60]输出: [1,1,1,0]示例 3:输入: temperatures = [30,60,90]输出: [1,1,0] 提示: 1 <= temperatures.length <= 10^5 30 <= temperatures[i] <= 100 💡 解题思路 方法一:单调栈 维护一个存储温度下标的栈,从栈底到栈顶,所索引的温度是递减的。 倒序遍历温度数组(倒序入栈 相当于 正序出栈),对于每一个索引 i: 只要栈不空,那么查看 temp...
LeetCode71 - 字符串解码
📝 题目描述 题目链接:字符串解码 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 测试用例保证输出的长度不会超过 10^5。 示例: 12345678910111213141516171819示例 1:输入:s = "3[a]2[bc]"输出:"aaabcbc"示例 2:输入:s = "3[a2[c]]"输出:"accaccacc"示例 3:输入:s = "2[abc]3[cd]ef"输出:"abcabccdcdcdef"示例 4:输入:s = "abc3[cd]xyz"输出:&quo...
LeetCode70 - 最小栈
📝 题目描述 题目链接:最小栈 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部的元素。 int top() 获取堆栈顶部的元素。 int getMin() 获取堆栈中的最小元素。 示例: 123456789101112131415161718示例 1:输入:["MinStack","push","push","push","getMin","pop","top","getMin"][[],[-2],[0],[-3],[],[],[],[]]输出:[null,null,null,null,-3,null,0,-2]解释:MinStack minStack = new MinStack();minStack.push...