zoukankan      html  css  js  c++  java
  • 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];
    				}
    			}
    		}
        }
    };
    
  • 相关阅读:
    学习进度条第一周
    构建之法阅读笔记01
    软件工程个人作业01
    《构建之法》阅读笔记
    Day6:闭包函数、无参装饰器
    Day5:函数参数
    Day4:字符编码与文件处理
    Day3:数据类型(布尔值、集合)
    Day2:数据类型(列表、元组、字典)
    Day1:初识Python
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7197834.html
Copyright © 2011-2022 走看看