提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、力扣509. 斐波那契数
- 二、力扣70. 爬楼梯
- 三、力扣746. 使用最小花费爬楼梯
- 四、力扣62. 不同路径
- 五、力扣63. 不同路径 II
- 六、力扣343. 整数拆分
- 七、力扣96. 不同的二叉搜索树
- 八、力扣46. 携带研究材料(第六期模拟笔试)
- 九、力扣46. 携带研究材料(第六期模拟笔试)
- 十、力扣416. 分割等和子集
- 十一、力扣1049. 最后一块石头的重量 II
- 十二、力扣494. 目标和
- 十三、力扣474. 一和零
- 十四、力扣52. 携带研究材料(第七期模拟笔试)
- 十五、力扣518. 零钱兑换 II
- 十六、力扣377. 组合总和 Ⅳ
- 十七、力扣57. 爬楼梯(第八期模拟笔试)
- 十八、力扣322. 零钱兑换
- 十九、力扣279. 完全平方数
- 二十、力扣139. 单词拆分
- 二十一、力扣56. 携带矿石资源(第八期模拟笔试)
- 二十二、力扣198. 打家劫舍
- 二十三、力扣213. 打家劫舍 II
- 二十四、力扣337. 打家劫舍 III
- 二十五、力扣121. 买卖股票的最佳时机
- 二十六、力扣122. 买卖股票的最佳时机 II
- 二十七、力扣123. 买卖股票的最佳时机 III
- 二十八、力扣188. 买卖股票的最佳时机 IV
- 二十九、力扣309. 买卖股票的最佳时机含冷冻期
- 三十、力扣714. 买卖股票的最佳时机含手续费
- 三十一、力扣300. 最长递增子序列
- 三十二、力扣674. 最长连续递增序列
- 三十二、力扣718. 最长重复子数组
- 三十三、力扣1143. 最长公共子序列
- 三十四、力扣1035. 不相交的线
- 三十五、力扣53. 最大子数组和
- 三十六、力扣392. 判断子序列
- 三十七、力扣115. 不同的子序列
- 三十八、力扣583. 两个字符串的删除操作
- 三十九、力扣72. 编辑距离
- 四十、力扣647. 回文子串
- 四十一、力扣516. 最长回文子序列
前言
确定dp数组及其下标含义
确定递推公式
dp数组如何初始化
确定遍历顺序
举例子推导dp数组
一、力扣509. 斐波那契数
class Solution {
public int fib(int n) {
int[] dp = new int[n+1];
if(n < 2){
return n;
}
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i ++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
二、力扣70. 爬楼梯
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
if(n <= 2){
return n;
}
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; i ++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
三、力扣746. 使用最小花费爬楼梯
class Solution {
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 0;
for(int i = 2; i <= n; i ++){
dp[i] = Math.min(dp[i-2]+cost[i-2], dp[i-1]+cost[i-1]);
}
return dp[n];
}
}
四、力扣62. 不同路径
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i = 0; i < n; i ++){
dp[0][i] = 1;
}
for(int i = 0; i < m; i ++){
dp[i][0] = 1;
}
for(int i = 1; i < m; i ++){
for(int j = 1; j <n; j ++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
五、力扣63. 不同路径 II
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
for(int i = 0; i < n; i ++){
if(obstacleGrid[0][i] == 0){
dp[0][i] = 1;
}else{
break;
}
}
for(int i = 0; i < m; i ++){
if(obstacleGrid[i][0] == 0){
dp[i][0] = 1;
}else{
break;
}
}
for(int i = 1; i < m; i ++){
for(int j = 1; j < n; j ++){
if(obstacleGrid[i][j] == 1){
dp[i][j] = 0;
}else{
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
}
六、力扣343. 整数拆分
class Solution {
public int integerBreak(int n) {
//dp 的定义是:下标为i的dp[i]表示 整数i拆分为若干个正整数之后的最大乘积
int[] dp = new int[n+1];
if(n <= 3){
return n-1;
}
dp[2] = 1;
dp[3] = 2;
for(int i = 4; i <= n; i ++){
for(int j = 1; j <= i/2; j ++){
dp[i] = Math.max(Math.max(dp[i-j]*j, (i-j)*j),dp[i]);
}
}
return dp[n];
}
}
七、力扣96. 不同的二叉搜索树
class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];
if(n <= 2){
return n;
}
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
dp[3] = 5;
for(int i = 4; i <= n; i ++){
for(int j = 1; j <= i; j ++){
dp[i] += (dp[j-1]*dp[i-j]);
}
}
return dp[n];
}
}
八、力扣46. 携带研究材料(第六期模拟笔试)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[] weight = new int[m];
int[] value = new int[m];
for(int i = 0; i <m; i ++){
weight[i] = sc.nextInt();
}
for(int i = 0; i <m; i ++){
value[i] = sc.nextInt();
}
int[][] dp = new int[m][n+1];
for(int i = 0; i <= n; i ++){
if(i >= weight[0]){
dp[0][i] = value[0];
}
}
for(int i = 1; i < m; i ++){
for(int j = 1; j <= n; j ++){
if(j >= weight[i]){
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(dp[m-1][n]);
}
}
九、力扣46. 携带研究材料(第六期模拟笔试)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[] weight = new int[m];
int[] value = new int[m];
for(int i = 0; i <m; i ++){
weight[i] = sc.nextInt();
}
for(int i = 0; i <m; i ++){
value[i] = sc.nextInt();
}
int[] dp = new int[n+1];
for(int i = 0; i < m; i ++){
for(int j = n; j >= weight[i]; j --){
dp[j] = Math.max(dp[j], dp[j-weight[i]] + value[i]);
}
}
System.out.println(dp[n]);
}
}
十、力扣416. 分割等和子集
class Solution {
public boolean canPartition(int[] nums) {
int sum = Arrays.stream(nums).sum();
if(sum % 2 == 1 || nums.length == 1){
return false;
}
sum /= 2;
int[] dp = new int[sum+1];
for(int i = 0; i < nums.length; i ++){
for(int j = sum; j >= nums[i]; j --){
dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
}
}
return dp[sum] == sum;
}
}
十一、力扣1049. 最后一块石头的重量 II
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = Arrays.stream(stones).sum();
int t = sum / 2;
int[] dp = new int[t+1];
for(int i = 0; i < stones.length; i ++){
for(int j = t; j >= stones[i]; j --){
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
return sum - 2*dp[t];
}
}
十二、力扣494. 目标和
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = Arrays.stream(nums).sum();
int r = (sum +target)/2;
if(sum < Math.abs(target) || (sum+target)%2 == 1){
return 0;
}
int n = nums.length;
int[][] dp = new int[n][r+1];
if(nums[0] <= r){
dp[0][nums[0]] = 1;
}
int zeroNum = 0;
for(int i = 0; i < n; i ++){
if(nums[i] == 0){
zeroNum ++;
}
dp[i][0] = (int)Math.pow(2, zeroNum);
}
for(int i = 1; i < n; i ++){
for(int j = 1; j <= r; j ++){
if(j >= nums[i]){
dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]];
}else{
dp[i][j] = dp[i-1][j];
}
}
}
return dp[n-1][r];
}
}
十三、力扣474. 一和零
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m+1][n+1];
for(String s : strs){
int zeroNum = 0, oneNum = 0;
for(char c : s.toCharArray()){
if(c == '0'){
zeroNum ++;
}else{
oneNum ++;
}
}
for(int i = m; i >= zeroNum; i --){
for(int j = n; j >= oneNum; j --){
dp[i][j] = Math.max(dp[i][j], dp[i-zeroNum][j-oneNum] + 1);
}
}
}
return dp[m][n];
}
}
十四、力扣52. 携带研究材料(第七期模拟笔试)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int v = sc.nextInt();
int[] weight = new int[n];
int[] value = new int[n];
for(int i = 0; i <n; i ++){
weight[i] = sc.nextInt();
value[i] = sc.nextInt();
}
int[][] dp = new int[n][v+1];
for(int i = weight[0]; i <= v; i ++){
dp[0][i] = dp[0][i-weight[0]] +value[0];
}
for(int i = 1; i < n; i ++){
for(int j = 0; j <= v; j ++){
if(j >= weight[i]){
dp[i][j] = Math.max(dp[i][j-weight[i]] + value[i], dp[i-1][j]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(dp[n-1][v]);
}
}
十五、力扣518. 零钱兑换 II
class Solution {
public int change(int amount, int[] coins) {
int m = coins.length;
int[] dp = new int[amount+1];
dp[0] = 1;
for(int i = 0; i < m; i ++){
for(int j = 1; j <= amount; j ++){
if(j >= coins[i]){
dp[j] += dp[j - coins[i]];
}
}
}
return dp[amount];
}
}
十六、力扣377. 组合总和 Ⅳ
class Solution {
public int combinationSum4(int[] nums, int target) {
int n = nums.length;
int[] dp = new int[target+1];
dp[0] = 1;
for(int i = 1; i <= target; i ++){
for(int j = 0; j < n; j ++){
if(i >= nums[j]){
dp[i] += dp[i-nums[j]];
}
}
}
return dp[target];
}
}
十七、力扣57. 爬楼梯(第八期模拟笔试)
import java.util.Scanner;
public class Main {
public static void main (String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 获取m的整数值
int m = scanner.nextInt(); // 获取n的整数值
int[] dp = new int[n + 1]; // 基于n的值创建数组
dp[0] = 1; // 初始化动态规划的基条件
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
if(i >= j){
dp[i] += dp[i-j];
}
}
}
System.out.println(dp[n]); // 正确地打印结果
scanner.close(); // 关闭scanner对象
}
}
十八、力扣322. 零钱兑换
class Solution {
public int coinChange(int[] coins, int amount) {
int n = coins.length;
int[] dp = new int[amount+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int i = 0; i < n; i ++){
for(int j = coins[i]; j <= amount; j ++){
int t = dp[j-coins[i]] == Integer.MAX_VALUE ? Integer.MAX_VALUE: dp[j-coins[i]]+1;
dp[j] = Math.min(dp[j], t);
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
}
十九、力扣279. 完全平方数
在这里插入代码片class Solution {
public int numSquares(int n) {
int m = (int)Math.sqrt(n);
int[] arr = new int[m+1];
for(int i = 1; i <= m; i ++){
arr[i] = i*i;
}
int[] dp = new int[n+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int i = 1; i <= m; i ++){
for(int j = arr[i]; j <= n; j ++){
if(dp[j - arr[i]] != Integer.MAX_VALUE){
dp[j] = Math.min(dp[j], dp[j-arr[i]]+1);
}
}
}
return dp[n];
}
}
二十、力扣139. 单词拆分
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] dp = new boolean[n+1];
dp[0] = true;
for(int j = 1; j <= n; j ++){
for(int i = 0; i < wordDict.size(); i ++){
String cur = wordDict.get(i);
int l = cur.length();
if(j >= cur.length()){
dp[j] = dp[j] || (dp[j - l] && fun(s,cur,l,j));
}
}
}
return dp[n];
}
public boolean fun(String s, String t, int l, int r){
for(int i = 0; i < t.length(); i ++){
if(s.charAt(r-l+i) != t.charAt(i)){
return false;
}
}
return true;
}
}
二十一、力扣56. 携带矿石资源(第八期模拟笔试)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int c = sc.nextInt();
int n = sc.nextInt();
int[] weight = new int[n];
int[] value = new int[n];
int[] nums = new int[n];
for(int i = 0; i < n; i ++){
weight[i] = sc.nextInt();
}
for(int i = 0; i < n; i ++){
value[i] = sc.nextInt();
}
for(int i = 0; i < n; i ++){
nums[i] = sc.nextInt();
}
int[] dp = new int[c+1];
for(int i = 0; i < n; i ++){
for(int j = 0; j < nums[i]; j ++){
for(int k = c; k >= weight[i]; k --){
dp[k] = Math.max(dp[k], dp[k-weight[i]] + value[i]);
}
}
}
System.out.println(dp[c]);
}
}
二十二、力扣198. 打家劫舍
class Solution {
public int rob(int[] nums) {
int n = nums.length;
int[] dp = new int[n+1];
dp[1] = nums[0];
if(n == 1){
return nums[0];
}
dp[2] = Math.max(nums[0], nums[1]);
if(n == 2){
return dp[2];
}
for(int i = 3; i <= n; i ++){
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
}
return dp[n];
}
}
二十三、力扣213. 打家劫舍 II
class Solution {
public int rob(int[] nums) {
int n = nums.length;
if(n == 1){
return nums[0];
}
if(n == 2){
return Math.max(nums[0], nums[1]);
}
return Math.max(fun(nums, 0, n-2), fun(nums, 1, n-1));
}
public int fun(int[] nums, int l, int r){
int[] dp = new int[r+1];
dp[l] = nums[l];
dp[l+1] = Math.max(nums[l], nums[l+1]);
for(int i = l+2; i <= r; i ++){
dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i]);
}
return dp[r];
}
}
二十四、力扣337. 打家劫舍 III
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int rob(TreeNode root) {
int[] res = fun(root);
return Math.max(res[0], res[1]);
}
// 0 已偷, 1 不偷
public int[] fun(TreeNode root){
if(root == null){
return new int[]{0,0};
}
int[] l = fun(root.left);
int[] r = fun(root.right);
int[] cur = new int[2];
cur[0] = root.val + l[1] + r[1];
cur[1] = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
return cur;
}
}
二十五、力扣121. 买卖股票的最佳时机
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][1], prices[i] + dp[i-1][0]);
}
return dp[n-1][1];
}
}
二十六、力扣122. 买卖股票的最佳时机 II
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]-prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
}
return dp[n-1][1];
}
}
二十七、力扣123. 买卖股票的最佳时机 III
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] dp = new int[n][4];
dp[0][0] = -prices[0];
dp[0][2] = -prices[0];
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i]);
dp[i][2] = Math.max(dp[i-1][2], dp[i][1] - prices[i]);
dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2] + prices[i]);
}
return Math.max(dp[n-1][1], dp[n-1][3]);
}
}
二十八、力扣188. 买卖股票的最佳时机 IV
class Solution {
public int maxProfit(int k, int[] prices) {
int n = prices.length;
int[][] dp = new int[n][2*k];
for(int i = 0; i < 2*k; i += 2){
dp[0][i] = -prices[0];
}
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
for(int j = 2; j < 2*k; j += 2){
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-1] - prices[i]);
dp[i][j+1] = Math.max(dp[i-1][j+1], dp[i-1][j] + prices[i]);
}
}
int res = 0;
for(int i = 1; i < 2*k; i += 2){
res = Math.max(dp[n-1][i],res);
}
return res;
}
}
二十九、力扣309. 买卖股票的最佳时机含冷冻期
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] dp = new int[n][4];
dp[0][0] = -prices[0];
//0 持有 1 之前就不持有 2 今天刚不持有 3 冷冻期
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], Math.max(dp[i-1][1], dp[i-1][3]) - prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][3]);
dp[i][2] = dp[i-1][0] + prices[i];
dp[i][3] = dp[i-1][2];
}
return Math.max(dp[n-1][1],Math.max(dp[n-1][2], dp[n-1][3]));
}
}
三十、力扣714. 买卖股票的最佳时机含手续费
class Solution {
public int maxProfit(int[] prices, int fee) {
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = -prices[0];
dp[0][1] = Math.max(0,-fee);
for(int i = 1; i < n; i ++){
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]-prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]-fee);
}
return Math.max(dp[n-1][0], dp[n-1][1]);
}
}
三十一、力扣300. 最长递增子序列
class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp, 1);
int res = 1;
for(int i = 1; i < n; i ++){
for(int j = 0; j < i; j ++){
if(nums[i] > nums[j]){
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}
三十二、力扣674. 最长连续递增序列
class Solution {
public int findLengthOfLCIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
int res = 1;
Arrays.fill(dp,1);
for(int i = 1; i < n; i ++){
if(nums[i] > nums[i-1]){
dp[i] = dp[i-1]+1;
}
res = Math.max(res,dp[i]);
}
return res;
}
}
三十二、力扣718. 最长重复子数组
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[][] dp = new int[m+1][n+1];
int res = 0;
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(nums1[i-1] == nums2[j-1]){
dp[i][j] = dp[i-1][j-1] + 1;
}
res = Math.max(res, dp[i][j]);
}
}
return res;
}
}
三十三、力扣1143. 最长公共子序列
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m = text1.length(), n = text2.length();
int[][] dp = new int[m+1][n+1];
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(text1.charAt(i-1) == text2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1]+1;
}else{
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[m][n];
}
}
三十四、力扣1035. 不相交的线
class Solution {
public int maxUncrossedLines(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[][] dp = new int[m+1][n+1];
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(nums1[i-1] == nums2[j-1]){
dp[i][j] = dp[i-1][j-1]+1;
}else{
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[m][n];
}
}
三十五、力扣53. 最大子数组和
class Solution {
public int maxSubArray(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
int res = dp[0];
for(int i = 1; i < n; i ++){
dp[i] = Math.max(dp[i-1]+nums[i], nums[i]);
res = Math.max(res, dp[i]);
}
return res;
}
}
三十六、力扣392. 判断子序列
class Solution {
public boolean isSubsequence(String s, String t) {
int m = s.length(), n = t.length();
int[][] dp = new int[m+1][n+1];
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(s.charAt(i-1) == t.charAt(j-1)){
dp[i][j] = dp[i-1][j-1] + 1;
}else{
dp[i][j] = dp[i][j-1];
}
}
}
return dp[m][n] == m;
}
}
三十七、力扣115. 不同的子序列
class Solution {
public int numDistinct(String s, String t) {
int m = s.length(), n = t.length();
int[][] dp = new int[m+1][n+1];
for(int i = 0; i <= m; i ++){
dp[i][0] = 1;
}
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(s.charAt(i-1) == t.charAt(j-1)){
dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
}else{
dp[i][j] = dp[i-1][j];
}
}
}
return dp[m][n] % Integer.MAX_VALUE;
}
}
三十八、力扣583. 两个字符串的删除操作
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
int[][] dp = new int[m+1][n+1];
for(int i = 0; i <= m; i ++){
dp[i][0] = i;
}
for(int j = 0; j <= n; j ++){
dp[0][j] = j;
}
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
dp[i][j] = Math.min(dp[i-1][j-1],Math.min(dp[i-1][j]+1, dp[i][j-1]+1));
}else{
dp[i][j] = Math.min(dp[i-1][j-1]+2,
Math.min(dp[i-1][j]+1, dp[i][j-1]+1)
);
}
}
}
return dp[m][n];
}
}
三十九、力扣72. 编辑距离
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
int[][] dp = new int[m+1][n+1];
for(int i = 0; i <= m; i ++){
dp[i][0] = i;
}
for(int j = 0; j <= n; j ++){
dp[0][j] = j;
}
for(int i = 1; i <= m; i ++){
for(int j = 1; j <= n; j ++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}else{
dp[i][j] = Math.min(dp[i-1][j],Math.min(dp[i-1][j-1], dp[i][j-1]))+1;
}
}
}
return dp[m][n];
}
}
四十、力扣647. 回文子串
class Solution {
public int countSubstrings(String s) {
int res = 0;
for(int i = 0; i < s.length(); i ++){
res += fun(i,i,s);
res += fun(i,i+1,s);
}
return res;
}
public int fun(int start, int end, String s){
int res = 0;
while(start >= 0 && end < s.length()){
if(s.charAt(start) != s.charAt(end)){
return res;
}else{
start --;
end ++;
res ++;
}
}
return res;
}
}
四十一、力扣516. 最长回文子序列
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[][] dp = new int[n+1][n+1];
for(int i = 0; i <= n; i ++){
dp[i][i] = 1;
}
for(int i = n-1; i >= 0; i --){
for(int j = i+1; j < n; j ++){
if(s.charAt(i) == s.charAt(j)){
dp[i][j] = dp[i+1][j-1] + 2;
}else{
dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][n-1];
}
}