[LeetCode]132. Palindrome Partitioning II

[LeetCode]132. Palindrome Partitioning II

题目描述

这里写图片描述

思路

动态规划
开始考虑,和单词划分很像
但是简单的遍历加计算是否回文串总共需要n^3的时间复杂度
优化:
先用动归判断字符串中的任一子串是否是回文串,这一过程可以在n^2时间复杂度完成,之后保存状态数组
之后动归来判断需要最少划分是多少,时间复杂度为n^2,在数组中查找是否回文串时间复杂度为常数
终极优化:
综合一起考虑
先初始化状态数组,每一位分别保存到当前位置的字符串需要切割的次数,初始化为当前字符串个数减一,之后进行遍历,对于第i位的字符,内层循环判断从i-j到i+j是否为回文串,如果是的话,那么dp[i + j + 1]位置的状态可以更新,注意在判断时需要考虑回文串是奇数个字符的回文串还是偶数个字符的回文串

代码

注释部分为自己写的优化部分
非注释部分是参考答案的最终优化

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
/*
public:
    void getPalinSubstr(string s) {
        isPalin.resize(s.size(), vector<int>(s.size()));
        for (int i = s.size() - 1; i >= 0; --i) {
            for (int j = i; j < s.size(); ++j) {
                if (i == j)
                    isPalin[i][j] = 1;
                else if (j == i + 1)
                    isPalin[i][j] = s[i] == s[j];
                else
                    isPalin[i][j] = s[i] == s[j] && isPalin[i + 1][j - 1];
            }
        }
    }
    int minCut(string s) {
        getPalinSubstr(s);
        vector<int> res(s.size());

        for (int i = 0; i < s.size(); ++i) {
            if (isPalin[0][i] == 1) {
                res[i] = 0;
            }
            else {
                res[i] = res[i - 1] + 1;
                for (int j = 0; j < i; ++j) {
                    if (isPalin[j + 1][i] == 1)
                        res[i] = min(res[i], res[j] + 1);
                }
            }
        }

        return res[s.size() - 1];
    }
private:
    vector<vector<int>> isPalin;
*/
public:
    int minCut(string s) {
        vector<int> dp(s.size() + 1);
        for (int i = 0; i <= s.size(); ++i)
            dp[i] = i - 1;
        for (int i = 1; i <= s.size(); ++i) {
            for (int j = 0; i - j >= 0 && i + j < s.size() && s[i - j] == s[i + j]; ++j)
                dp[i + j + 1] = min(dp[i + j + 1], 1 + dp[i - j]);
            for (int j = 0; i - j - 1 >= 0 && i + j < s.size() && s[i - j - 1] == s[i + j]; ++j)
                dp[i + j + 1] = min(dp[i + j + 1], 1 + dp[i - j - 1]);
        }
        return dp[s.size()];
    }

};

int main() {
    Solution s;
    cout << s.minCut("aab") << endl;

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值