Palindrome Partitioning I && II

(1) Palindrome Partitioning

动态规划,划分的时候判断dp_map[i][j]是否是回文串,需要用到dp_map[i+1][j-1]的值[1]:

class Solution {
private:
    void dp(string s, vector<vector<int>>& dp_map) {
        for(int i=s.size()-1;i>=0;i--)
            for(int j=i;j<s.size();j++)
            {
                if(i==j)
                    dp_map[i][j]=1;
                else
                {
                    if(s[i]==s[j])
                    {
                        if(i+1==j || dp_map[i+1][j-1]==1)
                            dp_map[i][j]=1;
                    }
                }
            }
    }
    
    void dfs(int dep, string &s, vector<vector<int>>& dp_map, vector<string> tmp, vector<vector<string>> &ret) {
        if(dep==s.size())
        {
            ret.push_back(tmp);
            return;
        }
        
        for(int i=dep;i<s.size();i++)
        {
            if(dp_map[dep][i]==1)
            {
                vector<string> tmp1(tmp);
                tmp1.push_back(s.substr(dep,i-dep+1));
                dfs(i+1,s,dp_map,tmp1,ret);
            }
        }
    }

public:
    vector<vector<string>> partition(string s) {
        vector<vector<int>> dp_map(s.size(),vector<int>(s.size(),0));
        vector<string> tmp; 
        vector<vector<string>> ret;
        
        if(s.size()==0)
            return ret;
        
        tmp.clear();
        ret.clear();
        
        dp(s,dp_map);
        dfs(0,s,dp_map,tmp,ret);
        
        return ret;
    }
};

注意用到二维数组时使用二维的vector来表达,这样可以免去一般二维数组的复杂传参。


(2) Palindrome Partitioning II

本来想在(1)的基础上在算出所有的可能切割组合中选一个最短的,还是超时了通不过。所以在寻找最少cut的时候还是得使用动态规划。这道题目的状态转移方程为:dp[i]=min(dp[j])+1,其中j>=0&&j<i&&p[j+1][i]是回文串,p[i][j]用来表示i-j之间是否是回文串[2]:

class Solution {
private:
    int dp(string s, vector<vector<int>>& dp_map) {
        for(int i=s.size()-1;i>=0;i--)
            for(int j=i;j<s.size();j++)
            {
                if(i==j)
                    dp_map[i][j]=1;
                else
                {
                    if(s[i]==s[j])
                    {
                        if(i+1==j || dp_map[i+1][j-1]==1)
                            dp_map[i][j]=1;
                    }
                }
            }
        
        int tmp;
        vector<int> dp_min(s.size(),0);
        for(int i=1;i<s.size();i++)
        {
            if(dp_map[0][i]==1)
                {
                    dp_min[i]=0;
                    continue;
                }
            
            tmp=numeric_limits<int>::max();
            for(int j=0;j<i;j++)
            {
                if(dp_map[j+1][i]==1)
                {
                    if(dp_min[j]+1<tmp)
                        tmp=dp_min[j]+1;
                }
            }
            dp_min[i]=tmp;
        }
        return dp_min[s.size()-1];
    }
    

public:
    int minCut(string s) {
        vector<vector<int>> dp_map(s.size(),vector<int>(s.size(),0));
 
        if(s.size()<=1)
            return 0;
        
        return dp(s,dp_map);
    }
};


参考:

[1] http://blog.csdn.net/worldwindjp/article/details/22042133

[2] http://blog.csdn.net/chen895281773/article/details/8780366

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值