algorithm/problem/leetcode/516
516. 最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
123输入:s = "bbbab"输出:4解释:一个可能的最长回文子序列为 "bbbb" 。
示例 2:
123输入:s = "cbbd"输出:2解释:一个可能的最长回文子序列为 "bb" 。
提示:
1 <= s.length <= 1000
s 仅由小写英文字母组成
区间dp(记忆化搜索)
123456789101112131415161718class Solution { public int longestPalindromeSubseq(String s) { char cs[] = s.toCharArray(); int n = cs.length; int memo[][] = new int[n][n]; ...
algorithm/problem/leetcode/45
45. 跳跃游戏 II
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
示例 1:
1234输入: nums = [2,3,1,1,4]输出: 2解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
12输入: nums = [2,3,0,1,4]输出: 2
提示:
1 <= nums.length <= 10^4
0 <= nums[i] <= 1000
题目保证可以到达 nums[n-1]
贪心(n):记录之前能到达的最远距离,当遍历到这个最远位置时,答案+1
123456789101112131415 ...
algorithm/problem/leetcode/3291
3291. 形成目标字符串需要的最少字符串数 I
给你一个字符串数组 words 和一个字符串 target。
如果字符串 x 是 words 中 任意 字符串的
前缀
,则认为 x 是一个 有效 字符串。
现计划通过 连接 有效字符串形成 target ,请你计算并返回需要连接的 最少 字符串数量。如果无法通过这种方式形成 target,则返回 -1。
示例 1:
输入: words = [“abc”,“aaaaa”,“bcdef”], target = “aabcdabc”
输出: 3
解释:
target 字符串可以通过连接以下有效字符串形成:
words[1] 的长度为 2 的前缀,即 "aa"。
words[2] 的长度为 3 的前缀,即 "bcd"。
words[0] 的长度为 3 的前缀,即 "abc"。
示例 2:
输入: words = [“abababab”,“ab”], target = “ababaababa”
输出: 2
解释:
target 字符串可以通过连接以下有效字符串形成:
words[ ...
algorithm/problem/leetcode/2560
2560. 打家劫舍 IV(2081)
沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。
由于相邻的房屋装有相互连通的防盗系统,所以小偷 不会窃取相邻的房屋 。
小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃取的 最大金额 。
给你一个整数数组 nums 表示每间房屋存放的现金金额。形式上,从左起第 i 间房屋中放有 nums[i] 美元。
另给你一个整数 k ,表示窃贼将会窃取的 最少 房屋数。小偷总能窃取至少 k 间房屋。
返回小偷的 最小 窃取能力。
示例 1:
12345678输入:nums = [2,3,5,9], k = 2输出:5解释:小偷窃取至少 2 间房屋,共有 3 种方式:- 窃取下标 0 和 2 处的房屋,窃取能力为 max(nums[0], nums[2]) = 5 。- 窃取下标 0 和 3 处的房屋,窃取能力为 max(nums[0], nums[3]) = 9 。- 窃取下标 1 和 3 处的房屋,窃取能力为 max(nums[1], nums[3]) = 9 。因此,返回 min(5, 9, 9) = 5 ...
algorithm/problem/leetcode/3148
3148. 矩阵中的最大得分(1820)
给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1 。
你可以从 任一 单元格开始,并且必须至少移动一次。
返回你能得到的 最大 总得分。
示例 1:
**输入:**grid = [[9,5,7,3],[8,9,6,1],[6,7,14,3],[2,5,3,1]]
**输出:**9
**解释:**从单元格 (0, 1) 开始,并执行以下移动:
- 从单元格 (0, 1) 移动到 (2, 1),得分为 7 - 5 = 2 。
- 从单元格 (2, 1) 移动到 (2, 2),得分为 14 - 7 = 7 。
总得分为 2 + 7 = 9 。
示例 2:
**输入:**grid = [[4,3,2],[3,2,1]]
输出:-1
**解释:**从单元格 (0, 0) 开始,执行一次移动:从 (0, 0) 到 (0, 1) 。得分为 3 - 4 = -1 。
提示:
m == g ...
algorithm/problem/leetcode/2858
2851. 字符串转换(2858)
给你两个长度都为 n 的字符串 s 和 t 。你可以对字符串 s 执行以下操作:
将 s 长度为 l (0 < l < n)的 后缀字符串 删除,并将它添加在 s 的开头。
比方说,s = 'abcd' ,那么一次操作中,你可以删除后缀 'cd' ,并将它添加到 s 的开头,得到 s = 'cdab' 。
给你一个整数 k ,请你返回 恰好 k 次操作将 s 变为 t 的方案数。
由于答案可能很大,返回答案对 10^9 + 7 取余 后的结果。
示例 1:
12345678910输入:s = "abcd", t = "cdab", k = 2输出:2解释:第一种方案:第一次操作,选择 index = 3 开始的后缀,得到 s = "dabc" 。第二次操作,选择 index = 3 开始的后缀,得到 s = "cdab" 。第二种方案:第一次操作,选择 index = 1 开始的后缀,得到 s = "bcda" 。第二次操作,选择 i ...
algorithm/problem/leetcode/509
509. 斐波那契数
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
12F(0) = 0,F(1) = 1F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。
示例 1:
123输入:n = 2输出:1解释:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:
123输入:n = 3输出:2解释:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:
123输入:n = 4输出:3解释:F(4) = F(3) + F(2) = 2 + 1 = 3
提示:
0 <= n <= 30
一维线性dp
123456789101112class Solution { public int fib(int n) { if (n == 0) return 0; int f[] = new int[n+1]; f[0] = 0 ...
algorithm/problem/leetcode/3202
3202. 找出有效子序列的最大长度 II(1974)
给你一个整数数组 nums 和一个 正 整数 k 。
nums 的一个
子序列
sub 的长度为 x ,如果其满足以下条件,则称其为 有效子序列 :
(sub[0] + sub[1]) % k == (sub[1] + sub[2]) % k == ... == (sub[x - 2] + sub[x - 1]) % k
返回 nums 的 最长****有效子序列 的长度。
示例 1:
**输入:**nums = [1,2,3,4,5], k = 2
**输出:**5
解释:
最长有效子序列是 [1, 2, 3, 4, 5] 。
示例 2:
**输入:**nums = [1,4,2,3,1,4], k = 3
**输出:**4
解释:
最长有效子序列是 [1, 4, 1, 4] 。
提示:
2 <= nums.length <= 10^3
1 <= nums[i] <= 10^7
1 <= k <= 10^3
值域dp
1234567891011121314151617class Sol ...
algorithm/problem/leetcode/2501
2501. 数组中最长的方波(1480)
给你一个整数数组 nums 。如果 nums 的子序列满足下述条件,则认为该子序列是一个 方波 :
子序列的长度至少为 2 ,并且
将子序列从小到大排序 之后 ,除第一个元素外,每个元素都是前一个元素的 平方 。
返回 nums 中 最长方波 的长度,如果不存在 方波 则返回 -1 。
子序列 也是一个数组,可以由另一个数组删除一些或不删除元素且不改变剩余元素的顺序得到。
示例 1 :
1234567输入:nums = [4,3,6,16,8,2]输出:3解释:选出子序列 [4,16,2] 。排序后,得到 [2,4,16] 。- 4 = 2 * 2.- 16 = 4 * 4.因此,[4,16,2] 是一个方波.可以证明长度为 4 的子序列都不是方波。
示例 2 :
123输入:nums = [2,3,5,6,7]输出:-1解释:nums 不存在方波,所以返回 -1 。
提示:
2 <= nums.length <= 10^5
2 <= nums[i] <= 10^5
12345678910111213141516 ...
algorithm/problem/leetcode/2901
2901. 最长相邻不相等子序列 II(1899)
给你一个整数 n 和一个下标从 0 开始的字符串数组 words ,和一个下标从 0 开始的数组 groups ,两个数组长度都是 n 。
两个长度相等字符串的 汉明距离 定义为对应位置字符 不同 的数目。
你需要从下标 [0, 1, ..., n - 1] 中选出一个 最长子序列,将这个子序列记作长度为 k 的 [i0, i1, ..., ik - 1] ,它需要满足以下条件:
相邻 下标对应的 groups 值 不同。即,对于所有满足 0 < j + 1 < k 的 j 都有 groups[ij] != groups[ij + 1] 。
对于所有 0 < j + 1 < k 的下标 j ,都满足 words[ij] 和 words[ij + 1] 的长度 相等 ,且两个字符串之间的 汉明距离 为 1 。
请你返回一个字符串数组,它是下标子序列 依次 对应 words 数组中的字符串连接形成的字符串数组。如果有多个答案,返回任意一个。
子序列 指的是从原数组中删掉一些(也可能一个也不删掉)元素,剩余元素不 ...