算法营day13--动态规划

牛客 palindrome-partitioning-ii

题目描述
给出一个字符串s,分割s使得分割出的每一个子串都是回文串
计算将字符串s分割成回文分割结果的最小切割数
例如:给定字符串s=“aab”,
返回1,因为回文分割结果[“aa”,“b”]是切割一次生成的。
思路:
代码:
用DP判断是否是回文字串

class Solution {
    
    
public:
    /**
     * 
     * @param s string字符串 
     * @return int整型
     */
    vector<vector<bool>> getMat(string& s){
    
    
        int n = s.size();
        vector<vector<bool>> Mat(n,vector<bool>(n,false));
        for(int i = n-1;i>=0;--i){
    
    
            for(int j = i;j<n;++j){
    
    
                if(j ==i){
    
    
                    Mat[i][j] =true;
                }
                else if(j == i+1){
    
    
                    Mat[i][j] = s[i] == s[j];
                }
                else
                    Mat[i][j] = (s[i] == s[j]) && (Mat[i+1][j-1]);
            }
        }
        return Mat;
    }
    int minCut(string s) {
    
    
        // write code here
        vector<vector<bool>> Mat;
        Mat=getMat(s);
        int len = s.size();
        vector<int> minCut(len+1);
        for(int i = 0; i <= len ;++i){
    
    //修改i的起始位置
            minCut[i] = i-1;
        }
        for(int i =2; i <= len; ++i){
    
    
            for(int j = 0; j < i;++j){
    
    //修改j的起始位置
                if(Mat[j][i-1]){
    
    //这里按要求修改
                    minCut[i] = min(minCut[i],minCut[j]+1);
                }
            }
        }
        return minCut[len];
    }
};

普通方法:

class Solution {
    
    
public:
    /**
     *
     * @param s string字符串
     * @return int整型
     */
    bool isPal(string& s, int start, int end){
    
    
        while(start < end){
    
    
            if(s[start] != s[end]){
    
    
                return false;
            }
            ++start,--end;
        }
        return true;
    }
    int minCut(string s) {
    
    
        // write code here
        int len = s.size();
        if(len == 0){
    
    
            return 0;
        }
        if(isPal(s,0,len-1))
            return 0;
        vector<int> minCut(len+1);
        for(int i = 0; i <= len ;++i){
    
    //修改i的起始位置
            minCut[i] = i-1;
        }
        for(int i =2; i <= len; ++i){
    
    
            for(int j = 0; j < i;++j){
    
    //修改j的起始位置
                if(isPal(s,j,i-1)){
    
    
                    minCut[i] = min(minCut[i],minCut[j]+1);
                }
            }
        }
        return minCut[len];
    }
};

牛客 编辑距离

题目描述
给定两个单词word1和word2,请计算将word1转换为word2至少需要多少步操作。
你可以对一个单词执行以下3种操作:
a)在单词中插入一个字符
b)删除单词中的一个字符
c)替换单词中的一个字符
思路:
代码:

class Solution {
    
    
public:
    /**
     * 
     * @param word1 string字符串 
     * @param word2 string字符串 
     * @return int整型
     */
    int mymin(int a, int b, int c){
    
    
        return min(a,min(b,c));
    }
    int minDistance(string word1, string word2) {
    
    
        // write code here
        int m = word1.size(),n=word2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        //base case
        for(int i = 1;i <= m; ++i)
            dp[i][0] = i;
        for(int j = 1;j <= n; ++j)
            dp[0][j] = j;
        //自底向上求解
        for(int i = 1; i <= m;++i){
    
    
            for(int j = 1; j <= n;++j){
    
    
                if(word1[i-1] == word2[j-1])
                    dp[i][j] = dp[i-1][j-1];
                else{
    
    
                    dp[i][j] = mymin(
                    dp[i-1][j] + 1,
                    dp[i][j-1] + 1,
                    dp[i-1][j-1] + 1
                    );
                }
            }
        }
        return dp[m][n];
    }
};

下面的表格可以帮助理解:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107730459