网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 其他技术区 > 算法与数据结构 >

算法day39-动态规划(12)

时间:2025-06-10 22:00

人气:

作者:admin

标签:

导读:目录 不同的子序列 两个字符串的删除操作 编辑距离 一、不同的子序列 https://leetcode.cn/problems/distinct-subsequences/?envType=problem-list-v2amp;envId=8At1GmaZ class Solution { pub...

目录

  1. 不同的子序列
  2. 两个字符串的删除操作
  3. 编辑距离

一、不同的子序列

 https://leetcode.cn/problems/distinct-subsequences/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int numDistinct(String s, String t) {
        //d[i][j]:以i-1结尾的s子序列中有以j-1结尾的t的个数
        int[][] dp = new int[s.length()+1][t.length()+1];
        for(int i=0; i<s.length()+1; i++){
            dp[i][0] = 1;
        }
        for(int i=1; i<s.length()+1; i++){
            for(int j=1; j<t.length()+1; j++){
                if(s.charAt(i-1) == t.charAt(j-1)){
                    //使用s.charAt(i-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()];
    }
}

 

二、两个字符串的删除操作

 https://leetcode.cn/problems/delete-operation-for-two-strings/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int minDistance(String word1, String word2) {
        //dp[i][j]:以i-1结尾的word1和以j-1结尾的word2变得结尾所需的最小步数
        int[][] dp = new int[word1.length()+1][word2.length()+1];
        for(int i=0; i<word1.length()+1; i++){
            dp[i][0] = i;
        }
        for(int j=0; j<word2.length()+1; j++){
            dp[0][j] = j;
        }
        for(int i=1; i<word1.length()+1; i++){
            for(int j=1; j<word2.length()+1; 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]+1, dp[i][j-1]+1);
                }
            }
        }
        return dp[word1.length()][word2.length()];

    }
}

 

三、编辑距离

 https://leetcode.cn/problems/edit-distance/description/?envType=problem-list-v2&envId=8At1GmaZ

 

1. 定义状态

定义一个二维数组 dp,其中 dp[i][j] 表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符所需的最小操作数。

2. 初始化

  • dp[0][j] = j:表示将空字符串转换为 word2 的前 j 个字符需要插入 j 个字符。

  • dp[i][0] = i:表示将 word1 的前 i 个字符转换为空字符串需要删除 i 个字符。

3. 状态转移

对于 dp[i][j]

  • 如果 word1.charAt(i-1) == word2.charAt(j-1),说明 word1[i-1]word2[j-1] 相同,不需要进行任何操作,此时 dp[i][j] = dp[i-1][j-1]

  • 如果 word1.charAt(i-1) != word2.charAt(j-1),我们需要选择以下三个操作中的最小代价:

    • 删除字符:dp[i-1][j] + 1,即从 word1 删除一个字符,保持 word2 不变。

    • 插入字符:dp[i][j-1] + 1,即向 word1 中插入一个字符,使其与 word2 匹配。

    • 替换字符:dp[i-1][j-1] + 1,即将 word1[i-1] 替换为 word2[j-1]

4. 返回结果

最后,dp[word1.length()][word2.length()] 即为将整个 word1 转换为 word2 的最小编辑距离。

时间复杂度

  • 时间复杂度:O(m * n),其中 mn 分别是 word1word2 的长度。我们需要遍历二维数组 dp,每个元素的填充操作是常数时间。

  • 空间复杂度:O(m * n),需要 O(m * n) 的空间来存储 dp 数组。

class Solution {
    public int minDistance(String word1, String word2) {
        int[][] dp = new int[word1.length()+1][word2.length()+1];
        for(int i=0; i<word1.length()+1; i++){
            dp[i][0] = i;
        }
        for(int j=0; j<word2.length()+1; j++){
            dp[0][j] = j;
        }
        for(int i=1; i<word1.length()+1; i++){
            for(int j=1; j<word2.length()+1; j++){
                if(word1.charAt(i-1) == word2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = Math.min(Math.min(dp[i-1][j]+1, dp[i][j-1]+1), dp[i-1][j-1]+1);
                }
            }
        }
        return dp[word1.length()][word2.length()];
    }
}

 

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信