LeetCode OJ 之 Palindrome Partitioning (字符串的回文分割)

题目:

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

给定一个字符串s,把它分割成每个子串都是回文形式,返回所有的分割可能。

For example, given s = "aab",
Return

  [
    ["aa","b"],
    ["a","a","b"]
  ]

思路:

该问题是一个典型的深搜问题,问题的解空间就是所有可能划分的划分树,我们只需要遍历所有的分支直到叶节点,即为一个可能的划分。即把字符串想象成一棵树。

代码1:

class Solution {
public:
    vector<vector<string>> partition(string s) 
    {
        vector<vector<string> > result;
        vector<string> path;
        dfs(s,path,result,0);
        return result;
    }
    void dfs(string &s,vector<string> &path,vector<vector<string> >&result,int start)
    {
        //start到底说明本次深搜完成,把path push进result中
        if(start == s.size())
        {
            result.push_back(path);
            return;
        }
        //否则,从start开始,对余下的字符串进行深搜
        for(int i = start ; i < s.size() ; i++)
        {
            //如果start到i是回文,则对i之后余下的进行深搜,如果不是回文,则 i++
            if(isPalindrome(s,start,i))
            {
                path.push_back(s.substr(start,i-start+1));
                dfs(s,path,result,i+1);
                path.pop_back();
            }
        }
    }
    //判断是否是回文
    bool isPalindrome(string &s , int start , int end)
    {
        while(start < end && s[start] == s[end])
        {
            ++start;
            --end;
        }
        return start >= end;
    }
};

DFS + DP方法.DP是用来求回文串的,具体可参考:http://blog.csdn.net/u012243115/article/details/41854563 .

代码2:

class Solution {
public:
    vector<vector<string>> partition(string s)
    {
        vector<vector<string>> result;
        vector<string> path;
        const int n = s.size();
        if (0 == n) 
            return result;
        vector<vector<bool> > isPalindrome(n, vector<bool>(n, false));
        //动态规划法求回文子串f(i,j)表示下标i到下标j之间的子串是否为回文子串,状态转移方程如下:
      //f( i, j) =   true ; i == j;
      //            s[i] == s[j] ;j = i + 1;//这个和上个两个总结在一起就是(s[i] == s[j]) && (j - i < 2 )
      //            s[i] == s[j] && f(i+1 , j-1); j > i + 1;//这个和上面两个总结在一起就是(s[i] == s[j]) && ((j - i < 2 ) || f(i+1 , j-1))
        for (int i = n - 1; i >= 0; i--)
        {
            for (int j = i; j < n; j++)
            {
                isPalindrome[i][j] = (s[i] == s[j]) && ((j - i < 2 ) || isPalindrome[i + 1][j - 1]);
            }
        }
        dfs(s,0,isPalindrome,result,path);
        return result;
    }
    void dfs(string s , int start , vector<vector<bool> > &isPalindrome , vector<vector<string> > &result , vector<string> &path)
    {
        if(start == s.size())
        {
            result.push_back(path);
            return;
        }
        for(int i = start ; i < s.size() ; i++)
        {
            if(isPalindrome[start][i])
            {
                path.push_back(s.substr(start,i-start+1));
                dfs(s,i+1,isPalindrome,result,path);
                path.pop_back();
            }
        }
    }
};


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值