lintcode-108-分割回文串 II

108-分割回文串 II

给定一个字符串s,将s分割成一些子串,使每个子串都是回文。
返回s符合要求的的最少分割次数。

样例

比如,给出字符串s = "aab",
返回 1, 因为进行一次分割可以将字符串s分割成["aa","b"]这样两个回文子串

标签

动态规划

方法一(大体上没问题,但会在样例aaa....aaa上超时)

使用一维数组 dp[i] 记录s[i]...s[n-1]的最小切割数,状态转移方程为:dp[i] = min{dp[j]+1, dp[i]} (j=i+1...n-1)

code

class Solution {
public:
    /**
     * http://www.lintcode.com/zh-cn/problem/palindrome-partitioning-ii/-108-分割回文串 II
     * @param s a string
     * @return an integer
     */
    int minCut(string s) {
        // write your code here
        int size = s.size(), i = 0, j = 0;
        if(size <= 0) {
            return 0;
        }

        vector<int> dp(size+1, 0x7FFFFFFF);
        for(i=size-1; i>=0; i--) {
            if(isPalindromeFun(s, i, size-1)) {
                dp[i] = 0;
                continue;
            }
            for(j=i+1; j<size; j++) {
                if(isPalindromeFun(s, i, j-1)) {
                    dp[i] = (dp[i] < dp[j]+1) ? dp[i] : dp[j]+1;
                }
            }
        }

        return dp[0];
    }

    bool isPalindromeFun(string s, int begin, int end) {
        for(int i=begin, j=end; i<j; i++, j--) {
            if(s[i] != s[j]) {
                return false;
            }
        }
        return true;
    }
};

方法二(改进了回文字符串的判断方式,Accept)

参考博客:http://www.tuicool.com/articles/Jbeuea
动态规划部分与方法一相同,只是改进了回文字符串的判断方式,不再是实时判断回文,而是将回文结果保存至二维数组 isPalindrome[i][j] 中,若 isPalindrome[i][j] = true,则 s[i]...s[j] 是回文串

code

class Solution {
public:
    /**
     * @param s a string
     * @return an integer
     */
    int minCut(string s) {
        // write your code here
        int size = s.size(), i = 0, j = 0;
        if(size <= 0) {
            return 0;
        }

        bool **isPalindrome = new bool*[size];
		for (i=0; i<size; i++) {
			isPalindrome[i] = new bool[size];
		}
		initIsPalindrome(isPalindrome, s);

        vector<int> dp(size+1, 0x7FFFFFFF);
        for(i=size-1; i>=0; i--) {
            if(isPalindrome[i][size-1]) {
                dp[i] = 0;
                continue;
            }
            for(j=i+1; j<size; j++) {
                if(isPalindrome[i][j-1]) {
                    dp[i] = (dp[i] < dp[j]+1) ? dp[i] : dp[j]+1;
                }
            }
        }

        return dp[0];
    }

    void initIsPalindrome(bool ** isPalindrome, const string& s) {
		int len = s.length();
		for (int L = 1; L <= len; ++L) {
			for (int i = 0; i < len - L + 1; ++i) {
				int j = i + L - 1;
				if (L == 1) {
					isPalindrome[i][j] = true;
				} else if (L == 2) {
					isPalindrome[i][j] = s[i] == s[j];
				} else {
					isPalindrome[i][j] = (s[i] == s[j]) && isPalindrome[i + 1][j - 1];
				}
			}
		}
    }
};
posted @ 2017-07-17 22:26  LiBaoquan  阅读(1593)  评论(0编辑  收藏  举报