LeetCode58 - 组合总和
📝 题目描述 题目链接:组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 对于给定的输入,保证和为 target 的不同组合数少于 150 个。 示例: 123456789101112131415161718示例 1:输入:candidates = [2,3,6,7], target = 7输出:[[2,2,3],[7]]解释:2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。7 也是一个候选, 7 = 7 。仅有这两种组合。示例 2:输入: candidates = [2,3,5], target = 8输出: [[2,2,2,2],[2,3,3],[3,5]]示例 3:输入: candidates = [2], target = 1输出...
LeetCode57 - 电话号码的字母组合
📝 题目描述 题目链接:电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例: 123456789示例 1:输入:digits = "23"输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]示例 2:输入:digits = "2"输出:["a","b","c"] 提示: 1 <= digits.length <= 4 digits[i] 是范围 ['2', '9'] 的一个数字 💡 解题思路 方法一:回溯 按照经典的回溯模板撰写即可。 首先使用一个二维数组存储每个数字对应的字母。 然后在回溯过程中,...
LeetCode56 - 子集
📝 题目描述 题目链接:子集 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集 (幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 数组的 子集 是从数组中选择一些元素(可能为空)。 示例: 123456789示例 1:输入:nums = [1,2,3]输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]示例 2:输入:nums = [0]输出:[[],[0]] 提示: 1 <= nums.length <= 10 -10 <= nums[i] <= 10 nums 中的所有元素 互不相同 💡 解题思路 方法一:递归 套用“全排列”的模板写法即可,不过这里由于 start 变量的存在,我们只能选择 start 之后的数字,避免了重复,因此可以舍弃 used 数组。 步骤: 首先用一个 track 来记录当前已经选好的数字序列。 子集长度从 0 到 n,用一个循环来遍历。 在每一层递归中,如果 track 长度达标则加入 ans 数组,否则从头到尾遍历整...
LeetCode55 - 全排列
📝 题目描述 题目链接:全排列 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例: 1234567891011121314示例 1:输入:nums = [1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2:输入:nums = [0,1]输出:[[0,1],[1,0]]示例 3:输入:nums = [1]输出:[[1]] 提示: 1 <= nums.length <= 6 -10 <= nums[i] <= 10 nums 中的所有整数 互不相同 💡 解题思路 方法一:回溯 把数组里的数字想象成放在桌子上的小球,我们要把它们依次放进一个个格子里。每次挑小球时,看看哪个还没被挑走,就把它放进格子里,然后继续挑下一个。 步骤: 状态记录:使用了 used 布尔数组来记录哪些数字已经被选过了,用一个 track 来记录当前已经选好的数字序列。 递归填数:在每一层递归中,从头到尾遍历整个 nums 数组。 剪枝与选择:如果发现 ...
LeetCode54 - 实现 Trie (前缀树)
📝 题目描述 题目链接:实现 Trie (前缀树) Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。 请你实现 Trie 类: Trie() 初始化前缀树对象。 void insert(String word) 向前缀树中插入字符串 word 。 boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。 boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。 示例: 1234567891011121314输入["Trie", "insert", "search", "search", "startsWith", "insert&q...
LeetCode53 - 课程表
📝 题目描述 题目链接:课程表 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [a_i, b_i] ,表示如果要学习课程 a_i 则 必须 先学习课程 b_i 。 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。 示例: 1234567891011示例 1:输入:numCourses = 2, prerequisites = [[1,0]]输出:true解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。示例 2:输入:numCourses = 2, prerequisites = [[1,0],[0,1]]输出:false解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 ...
LeetCode52 - 腐烂的橘子
📝 题目描述 题目链接:腐烂的橘子 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2 代表腐烂的橘子。 每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。 示例: 示例 1: 12输入:grid = [[2,1,1],[1,1,0],[0,1,1]]输出:4 示例 2: 123输入:grid = [[2,1,1],[0,1,1],[1,0,1]]输出:-1解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。 示例 3: 123输入:grid = [[0,2]]输出:0解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。 提示: m == grid.length n == grid[i].length 1 <= m, n <= 10 grid[i][j] 仅为 0、1 或 2 💡 解题思路 方法一:多源广度优先搜索 这道题本质...
LeetCode51 - 岛屿数量
📝 题目描述 题目链接:岛屿数量 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包围。 示例: 12345678910111213141516171819示例 1:输入:grid = [ ['1','1','1','1','0'], ['1','1','0','1','0'], ['1','1','0','0','0'], ['0','0','0','0','0']]输出:1示例 2:输入:grid = [ [...
LeetCode50 - 二叉树中的最大路径和
📝 题目描述 题目链接:二叉树中的最大路径和 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root ,返回其 最大路径和 。 示例: 示例 1: 123输入:root = [1,2,3]输出:6解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6 示例 2: 123输入:root = [-10,9,20,null,null,15,7]输出:42解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42 提示: 树中节点数目范围是 [1, 3 * 10^4] -1000 <= Node.val <= 1000 💡 解题思路 方法一:递归 首先不要被“路径还能横着走”吓到。 思考:参考“最大子数组和”,对于一个节点,如何计算它的单边最大贡献值? 我们思考从上到下单走一条路的情况,也即只选择它的左右...
LeetCode49 - 二叉树的最近公共祖先
📝 题目描述 题目链接:二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 示例: 示例 1: 123输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出:3解释:节点 5 和节点 1 的最近公共祖先是节点 3 。 示例 2: 123输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4输出:5解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。 示例 3: 12输入:root = [1,2], p = 1, q = 2输出:1 提示: 树中节点数目在范围 [2, 105] 内 -10^9 <= Node.val <= 10^9 所有 Node.val 互不相同 p != q p 和 q 均存在于给定...