Leecode第5题:最长回文子串——动态规划法

在《算法图解》中看到动态规划算法,一直没有进行练习,今天恰好在Leecode刷到本题,可以用动态规划求解。动态规划法解决的问题一般是各种各样从表面上需要全部枚举各种情况的问题,其核心是通过把大问题分解成子问题,从而减小计算量。比如本题中的状态转移方程。状态规划法的时间复杂度一般为O(n2)。
代码和解题用的图如下。
/*****  Leecode Q5:最长回文子串  *****/
/*****  Author:Daniel           *****/
/*****  Algorith:动态规划        *****/
//动态规划解法
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Solution
{
public:
    string longestPalindrome(string s)
    {
        int len = s.size();
        string ans;
        //初始化一个容器存储 动态规划的列表
        vector<vector<int>> dp(len, vector<int>(len));
        int maxlen = 0;
        int start = 0, end = 0, move = 0;
        //先填写对角线的值,然后再根据对角线的值求解其他值
        //转移方程   dp[start][end] = (dp[start + 1][end - 1]) && (s[start] == s[end])
        //其中间隔为0和间隔为1是特殊情况,无法使用转移方程,因此对此种情况进行讨论
        for (move = 0; move < len; move++)
        {
            for (start = 0; start + move < len; start++)
            {
                end = start + move;
                //先填写对角线的值,这是动态规划的基础值
                if (move == 0)
                {
                    dp[start][end] = 1;
                }
                //当子串是两个字符时,依然无法通过状态转移方程判断是否是回文串
                else if (move == 1)
                {
                    dp[start][end] = (s[start] == s[end]);
                }
                //当子串字符数>=3时
                else
                {
                    dp[start][end] = (dp[start + 1][end - 1]) && (s[start] == s[end]);
                }
                //和最大值进行比较,如大于最大值,则更新最大值
                if (dp[start][end] == 1 && move + 1 > maxlen)
                {
                    ans = s.substr(start, move + 1);
                    maxlen = move + 1;
                }
            }
        }
        return ans;
    }
};
int main(int argc, char **argv)
{
//测试案例
    Solution sl;
    cout << sl.longestPalindrome("aaaa") << endl;
    cout << sl.longestPalindrome("abadc") << endl;
    cout << sl.longestPalindrome("wewexseabbadw") << endl;
    return 0;
}

动态规划图片示意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值