01 2021 档案
摘要:方法1:动态规划。类似于最长上升子序列问题。 时间复杂度为O(n^2), 空间复杂度:O(n) 先将所有的 n 个区间按照左端点从小到大进行排序,随后使用动态规划的方法求出区间数量的最大值。 ☆☆☆☆方法2【最优解】:贪心算法。时间复杂度:O(nlogn), 空间复杂度:O(logn) 每次选择中,
阅读全文
摘要:思路1:双指针。每次贪心的匹配,如果匹配成功则同时右移。 ☆☆☆思路2:动态规划。 代码1: class Solution { public boolean isSubsequence(String s, String t) { // 时间复杂度: O(n+m) 空间复杂度:O(1) int si
阅读全文
摘要:思路:排序 + 贪心算法 每次拿最大的饼干与最贪心的小朋友进行比较,如果满足,则可以让其满足;否则,继续找下一个小朋友。 由于贪心算法通常每一次操作都需要取最大值或最小值,因此需要对数组排序。 class Solution { public int findContentChildren(int[]
阅读全文
摘要:☆☆☆☆思路:哈希表。参考 官方题解 class Solution { public int longestConsecutive(int[] nums) { Set<Integer> set = new HashSet<>(); for (int num : nums) { set.add(num
阅读全文
摘要:class Solution { /** * 最优子结构:在i处递减的摆动序列的总长度,就是在i之前以递增结尾的最长摆动序列长度 +1; * 状态定义:up[i] 表示以前 i 个元素中的某一个为结尾的最长的 上升摆动序列 的长度 * down[i] 表示以前 i 个元素中的某一个为结尾的最长的 下
阅读全文
摘要:☆☆☆☆思路:Longest Common Sequence (LCS) 问题。要对两个字符串进行扫描,因此需要两个维度进行动态规划。 1. 状态的定义:dp[m][n] 表示 S1[0...m] 和 S2[0...n] 的最长公共子序列的长度。 2. 状态转移:每次对最新需要考虑的字符,s1[m]
阅读全文
摘要:class Solution { public int findLengthOfLCIS(int[] nums) { if (nums == null || nums.length == 0) return 0; int res = 1; int len = 1; for (int i = 1; i
阅读全文
摘要:☆☆☆☆思路:本题是经典的LIS问题。两种解法,动态规划 和 二分查找。 方法1:动态规划。时间复杂度为O(n^2) 方法2:二分查找,时间复杂度为O(nlogn) 【举一反三】: (1)该题为不连续的情况,延伸求最长连续递增子序列长度,见LeetCode674. 最长连续递增序列 (2)除了要会求
阅读全文
摘要:☆☆☆☆思路:把所有符号为正的数总和设为一个背包的容量,容量为x;把所有符号为负的数总和设为一个背包的容量,容量为y。 令sum为数组的总和,则x+y = sum。而两个背包的差为S,则x-y=S。从而求得x=(S+sum)/2。 因此,题目转换为0-1背包问题:给定一个数组和一个容量为x的背包,求
阅读全文
摘要:class Solution { /** * 举个例子: * dp["onetwothreefour"] = dp["onetwothree"这一段] && 判断一下"four" */ public boolean wordBreak(String s, List<String> wordDict)
阅读全文
摘要:题目解释:用 m 个0 和 n 个1,最多可以组成数组中的多少个01串? 示例2之所以不能是 “10”,原因是虽然1个0和1个1可以组成“10”,但只组成了数组中的1个元素,不是最大的。 ☆☆☆☆思路:本题是二维的0-1背包问题,把总共的 0 和 1 的个数视为背包的容量 0-1背包,即数组中的元素
阅读全文
摘要:思路:类似于爬楼梯问题。楼梯的阶数一共为target,一次可以走的步数为nums[i]。 一共有多少种走法? 爬楼梯问题,target在外层。 也可以看成 完全背包问题,即数组中的元素可重复使用。技巧是 nums放在外循环,target在内循环。且内循环正序。 但是如果组合问题需考虑元素之间的顺序,
阅读全文
摘要:思路:类似于跳台阶(爬楼梯)问题。 爬楼梯问题的 target 在外层。 class Solution { /** * 思路; 转化为跳台阶问题 * 1. 状态的定义: dp[i] 表示到i台阶时的最小步数, 也即凑齐i需要的最少硬币数 * 2. 状态转移方程 dp[i] = min {dp[i-c
阅读全文
摘要:☆☆☆☆☆思路:转化为0-1背包问题。 即,是否可以从输入数组中挑出一些正整数,使得这些数的和 等于 整个数组和的一半。 本题与传统0-1背包问题的不同在于,传统0-1 背包问题要求 选取的物品的重量之和 不能超过 背包的容量;而本题选取的数字之和需要 恰好等于 规定的和的一半。 这一点的区别,决定
阅读全文
摘要:class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length == 0) return 0; int len = prices.length; int[][] dp = new in
阅读全文
摘要:☆☆☆☆思路:树形DP问题。 class Solution { /** * 1.状态的定义:dp[node][j] 表示 node是否偷取所能获得的最大价值。 * j = 0, 表示node节点不偷 ; j = 1, 表示node结点偷取 * 2.状态转移方程: * 如果当前节点偷,那么左右子节点均
阅读全文
摘要:思路:与198题的区别是,本题的房子时环形的,即首位连接。 首先,首尾房间不能同时被抢,那么只可能有三种不同情况:要么都不被抢;要么第一间房子被抢最后一间不抢;要么最后一间房子被抢第一间不抢。 但是,只需要考虑情况二和情况三,取两种情况最大的即可。 因为,在计算这两种情况时,已经把都不抢的情况考虑到
阅读全文
摘要:思路:状态的定义很重要。 状态定义1: dp[i]表示 到第 i 个房子的最大金额 class Solution { /** * dp[n]表示 到第n个房子的最大金额 * 1.如果偷第n个房子,由于不能相邻,dp[n]= dp[n-2] + nums[n] * 2.如果不偷第n个房子,那么dp[n
阅读全文
摘要:class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length, n = obstacleGrid[0].length; // dp[i][j] 表示 (
阅读全文
摘要:思路:本题类似于LeetCode64. 最小路径和 class Solution { public int uniquePaths(int m, int n) { // dp[i][j] 表示 从(0,0) 到 (i,j)有多少不同的路径 int[][] dp = new int[m][n]; //
阅读全文
摘要:☆☆☆思路:本题可以看成约束版的“爬楼梯问题”,即约束版的 f(n) = f(n-1) + f(n-2) 问题。 注意点1:由于 i 取 1 时,dp[len-2]取不到,所以要有n+1个。len-2决定了 dp[i] 应定义为 字符个数为i的方法总数。 注意点2:对于dp[0]的初值,举例如"12
阅读全文
摘要:思路: 画出递归树可以看出,存在重叠子问题,且具有最优子结构,因此可以使用 动态规划 解决。 (1)使用递归进行编码, 提交到力扣会超时 class Solution { public int integerBreak(int n) { return breakInteger(n); } // 将n
阅读全文