首页 > 编程语言 >代码随想录算法训练营 | 115.不同的子序列,583. 两个字符串的删除操作,72. 编辑距离

代码随想录算法训练营 | 115.不同的子序列,583. 两个字符串的删除操作,72. 编辑距离

时间:2024-10-18 21:33:46浏览次数:7  
标签:583 int 随想录 115 length word1 word2 dp String

115.不同的子序列
题目链接:115.不同的子序列
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰不同的子序列
日期:2024-10-18

想法:dp[i][j]表示以s[i -1],t[j - 1]结尾的s,t自学列中满足s的子序列为t的个数,如果s[i -1],t[j - 1]相等,那么个数应该跟双方上一个结尾状态dp[i - 1][j - 1]一样,但由于还有像dogg和dog这种情况,还需要t当前的序列跟s的上一个长度序列进行计算,即dp[i - 1][j],这个状态也要考虑,如果不等就比较简单只用考虑s上一个状态对应此时的t就行了即dp[i - 1][j];初始化dp[0][j](j > 0)显然不会有空的s满足不空的t,全为0,dp[i][0](i > 0)s的子序列都可以删减到空,有一个能满足,dp[i][0] = 1,dp[0][0]考虑到空s删除0个字符得到空t,可以视为1,也可以从如果s[0] = t[0]得到dp[1][1] = 1推出dp[0][0]要为1.
Java代码如下:

class Solution {
    public int numDistinct(String s, String t) {
        char[] charS = s.toCharArray();
        char[] charT = t.toCharArray();
        int[][] dp = new int[s.length() + 1][t.length() + 1];
        for(int i = 0; i <= s.length(); i++) {
            dp[i][0] = 1;
        }
        for(int i = 1; i <= s.length(); i++) {
            for(int j = 1; j <= t.length(); j++) {
                if(charS[i - 1] == charT[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
                }else dp[i][j] = dp[i - 1][j];
            }
        }
        return dp[s.length()][t.length()];
    }
}

583. 两个字符串的删除操作
题目链接:583. 两个字符串的删除操作
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰两个字符串的删除操作
日期:2024-10-18

想法:思路1:dp[i][j]以i-1,j-1为结尾的字符串word1,word2,想要达到相等,所需要删除元素的最少次数。当word1[i - 1],word2[j - 1]相等时,这两个就不用删了,那么次数跟上一次的相等,即dp[i - 1][j - 1],不等时,就要考虑是删word1还是word2,还是两个一起,分别是dp[i - 1][j] + 1,dp[i][j - 1] + 1,dp[i - 1][j - 1] + 2。初始化显然dp[i][0] = i,dp[0][j] = j,有多少字符删多少到空。
Java代码如下:
思路2:找word1,word2的最长子序列长度,然后减。

//思路1
class Solution {
    public int minDistance(String word1, String word2) {
        char[] char1 = word1.toCharArray();
        char[] char2 = word2.toCharArray();
        int[][] dp = new int[word1.length() + 1][word2.length() + 1];
        for(int i = 0; i <= word1.length(); i++) dp[i][0] = i;
        for(int i = 0; i <= word2.length(); i++) dp[0][i] = i;

        for(int i = 1; i <= word1.length(); i++) {
            for(int j = 1; j <= word2.length(); j++) {
                if(char1[i - 1] == char2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = Math.min(dp[i - 1][j] + 1, Math.min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 2));
                }
            }
        }
        return dp[word1.length()][word2.length()];
    }
}
//思路2
class Solution {
    public int minDistance(String word1, String word2) {
        char[] char1 = word1.toCharArray();
        char[] char2 = word2.toCharArray();
        int[][] dp = new int[word1.length() + 1][word2.length() + 1];

        for(int i = 1; i < word1.length() + 1; i++) {
            for(int j = 1; j < word2.length() + 1; j++) {
                if(char1[i - 1] == char2[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 word1.length() + word2.length() - 2 * dp[word1.length()][word2.length()];
    }
}

72. 编辑距离
题目链接:72. 编辑距离
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰编辑距离
日期:2024-10-18

想法:dp[i][j]表示以word1[i - 1]word2[j - 1]结尾的word1,word2的子序列从1变到2最少步骤;word1[i - 1]word2[j - 1]相等,这个位置不用变化,保持前个位置的次数就行即dp[i - 1][j - 1],不同的时候,考虑改变的操作有三种,增删改,word1增可以等效于word2删一个(a, ad)即dp[i][j - 1] + 1;word1删,dp[i - 1][j] + 1;改,将word1[i - 1],word2[j - 1]改为相等,在前个位置的次数基础上再加一就行了即dp[i - 1][j - 1] + 1,最后看这三种那种次数最少。初始化,都是有多少位删(加)到多少位。
Java代码如下:

class Solution {
    public int minDistance(String word1, String word2) {
        char[] char1 = word1.toCharArray();
        char[] char2 = word2.toCharArray();
        int[][] dp = new int[word1.length() + 1][word2.length() + 1];
        for(int i = 0; i <= word1.length(); i++) dp[i][0] = i;
        for(int j = 0; j <= word2.length(); j++) dp[0][j] = j;

        for(int i = 1; i <= word1.length(); i++) {
            for(int j = 1; j <= word2.length(); j++) {
                if(char1[i - 1] == char2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1] + 1, Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1));
                }
            }
        }
        return dp[word1.length()][word2.length()];
    }
}

标签:583,int,随想录,115,length,word1,word2,dp,String
From: https://www.cnblogs.com/wowoioo/p/18475093

相关文章

  • 代码随想录算法训练营 | 1143.最长公共子序列,1035.不相交的线,53. 最大子序和,392.判断
    1143.最长公共子序列题目链接:1143.最长公共子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰最长公共子序列日期:2024-10-17想法:这里的子序列不要求连续了,dp[i][j]要表示为在text1[0,i-1]和text2[0,j-1]的范围里,最长的公共子序列长度,-1同样是为了初始化方便,如果te......
  • 代码随想录算法训练营第二天|209长度最小的子数组、59螺旋矩阵
    1leetcode209长度最小的子数组题目链接:209.长度最小的子数组文章链接:代码随想录(programmercarl.com)视频链接:拿下滑动窗口!|LeetCode209长度最小的子数组思路:没有思路,看到这道题有一种想立马退出的感觉,无从下手1.1暴力搜索1.1.1python版本这个版本的新知识就是定义......
  • 代码随想录|二叉树part 03
    求普通二叉树的节点数量要点:将子节点的个数记录到父节点,使用后序遍历classSolution{public:intmaxDepth(TreeNode*root){if(root==NULL)return0;intleft1=maxDepth(root->left);intright1=maxDepth(root->right);intnum=......
  • 代码随想录|二叉树part 02
    翻转二叉树要点:指针交换优先利用前序或后序遍历,若采用中序遍历(则两次采用遍历左子树)classSolution{public:TreeNode*invertTree(TreeNode*root){if(root==NULL)returnroot;swap(root->left,root->right);invertTree(root->left);......
  • 20241016每日一题洛谷P1115
    普及-洛谷P1115最大子段和读题可知需要在一段一维数组中寻找一段唯一的区间,使区间内的数和最大,即寻找和最大区间可以想到前缀和的算法假设输入数组a[n]则前缀和数组b[n]=b[n-1]+a[n]那么从什么时候开始的一段区间才能使区间内的数和最大?从前缀和数组逐步来判断这一条......
  • 代码随想录算法训练营 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数
    300.最长递增子序列题目链接:300.最长递增子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰最长递增子序列日期:2024-10-16想法:dp[i]表示以nums[i]结尾的最长子数列长度,需要知道i之前的j的dp[j],找到最大的dp[j],再加1,初始化都为1。Java代码如下:classSolution{pub......
  • 代码随想录训练营第64天|bellman_ford
    47.参加科学大会#include<iostream>#include<vector>#include<list>#include<queue>#include<climits>usingnamespacestd;//小顶堆classmycomparison{public:booloperator()(constpair<int,int>&lhs,constpai......
  • 代码随想录训练营第58天|统计相邻
    110.字符串接龙#include<iostream>#include<vector>#include<string>#include<unordered_set>#include<unordered_map>#include<queue>usingnamespacestd;intmain(){stringbeginStr,endStr,str;intn;ci......
  • 代码随想录算法训练营day17| 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜
    学习资料:https://programmercarl.com/0654.最大二叉树.html#算法公开课用前序遍历构造二叉树二叉搜索树的特点,其左节点的值<每个节点的值<其右节点的值,且根节点的值大于它的左子树的所有节点的值,小于它右子树的所有节点的值,其他同理。二叉搜索树的搜索和验证时不关心遍历顺序,因......
  • 代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方
    代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方1Leetcode704二分查找题目链接:[704.二分查找](704.二分查找-力扣(LeetCode))文章链接:[代码随想录](代码随想录(programmercarl.com))视频链接:[手把手带你撕出正确的二分法|二分查找法|二分搜......