经典的动态规划问题

动态规划

定义:

是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
       动态规划常常适用于有重叠子问题[1]和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
       动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。
       通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。
       动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。

适用条件

  1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
  2. 无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
  3. 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

关于本题

当你看到最X的什么的时候,很容易想到动态规划。(虽然不是什么都能用)恰好这道题可以使用动态规划解决。

  • 0 <= i < s.size()0 <= j < s.size()
  • table[i][j] == true 表示从 i + 1j + 1 的字符串是一个回文字符串
  • table[i + 1][j - 1] == trues[i] == s[j] 表明了从 i + 2js 子串是一个回文字符串并且第 i + 1j + 1 位置的字符是相同的
  • 自然从 i + 1j + 1 的字符串是一个回文字符串

开始

实际上,根据上面的解释和题面我们知道,我们需要找出 s 的子串,可以归结为找出子串的 start 和 end 然后使用 subString 直接取出子串。即得到 table[i][j] = true 且 这时候 j - i 为所有满足该条件的 i、j 中最大的。
       只要我们求出了 table 中所有位置的值,那么要找到结果是轻而易举的。
       我们把子问题归结为:table[i][j] 的值应该为什么。
       而上面那个步骤,就是求解这个问题的子问题的方法。

起始
i == j 的时候,子串 [i...j] 一定是回文的(一个字符肯定回文),美好的时光开始了。

不说废话,上完整代码

class Solution {
public:string longestPalindrome(string str) {if (str.size() == 0) return "";if (str.size() == 1) return str;int s = 0, f = 1;for (int i = 0; i < str.size();) {if (str.size() - i <= f / 2) break;int j = i, k = i;while (k < str.size()-1 && str[k+1] == str[k]) {++k;}i = k+1;while (k < str.size()-1 && j > 0 && str[k + 1] == str[j - 1]) {++k;--j;}int len = k - j + 1;if (len > f) {s = j;f = len;}}return str.substr(s, f);}
};

接下来我会一步一步解释的

if (str.size() == 0) return "";
if (str.size() == 1) return str;

s 为空,没有子串。
s 为一个字符,子串就是本身。

int s = 0, f = 1;

这里 s 表示子串开始位置,f 表示子串结束位置。

for (int i = 0; i < str.size();)

理论上是要遍历一遍 s 然后对每个位置进行回文子串计算。

if (str.size() - i <= f / 2) break;

如果已经知道就算当前计算出的回文子串的长度肯定小于已经计算出来的,那么不必计算了,直接返回结果。

int j = i, k = i;
while (k < str.size() - 1 && str[k + 1] == str[k]) {++k;
}
i = k+1;

这里是一个优化,遇到了 aaaaab 这种字符串的话就不必计算回文字串,直接把 k 移动到最后一位然后继续进行计算,并且把 i 也移动到最后一位。

while (k < str.size()-1 && j > 0 && str[k + 1] == str[j - 1]) {++k;--j;
}

核心代码,这里就是刚才列出的计算过程。

int len = k - j + 1;
if (len > f) {s = j;f = len;
}

如果计算出的回文子串与之前计算出的长度相比较大就将 s 和 f 重新定位到新的回文子串

return str.substr(s, f);

返回结果

总结

这只是一个较为简单的动态规划问题,鄙人不才无法想到 O(n) 的解法,如果有某些大神可以使用 O(n) 复杂度的算法解决这个问题,请务必告诉我。

LeetCode 5.Longest Palindromic Substring 求解相关推荐

  1. 【回文串1 动态规划 马拉车算法】LeetCode 5. Longest Palindromic Substring

    LeetCode 5. Longest Palindromic Substring LeetCode中与回文串相关的免费的题目共有15道(5, 9, 125, 131, 132, 214, 234, ...

  2. LeetCode 5. Longest Palindromic Substring 最长回文子串 Python 四种解法(Manacher 动态规划)

    Longest Palindromic Substring 最长回文子串 学习笔记 1. Brute method 第一种方法:直接循环求解,o(n2)o(n^2) class Solution:de ...

  3. [LeetCode]--5. Longest Palindromic Substring

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  4. leetcode 5 :Longest Palindromic Substring 找出最长回文子串

    题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum l ...

  5. [*leetcode 5] Longest Palindromic Substring

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  6. leetcode 5 Longest Palindromic Substring Java JavaScript解法

    题目详情 Given a string s, find the longest palindromic substring in s. You may assume that the maximum ...

  7. [LeetCode] 5. Longest Palindromic Substring

    这道题可以用动态规划,但是其实中心枚举更直接并符合逻辑,需要注意的是,以每一个字母为中心查找最大的Palindromic string的时候是有两种情况,第一种是以这个单一字母为中心(aba),第二个 ...

  8. leetcode 5. Longest Palindromic Substring 字符串中的最长回文数 逐步从O(n^2)优化至线性时间

    题目 解析 思路一 暴力解法 思路二 指针+最大长度 思路3 由中间至两边找回数 思路4 Manacher's algorithm 线性时间 参考文档 题目 链接 给定一个字符串 s,找到 s 中最长 ...

  9. [dp]Leetcode 5. Longest Palindromic Substring

    输入:一个字符串s 输出:最长的回文子串 规则:"abba"是一个回文 分析:输入是"babad",输出"bab".这个问题不能再按照之前分 ...

最新文章

  1. C++ 通过模版工厂实现 简单反射机制
  2. linux写文件优化,Linux文件系统性能优化
  3. python pdf报告_Python实现html转换为pdf报告(生成pdf报告)功能示例
  4. 算法的封装与切换——策略模式
  5. SAP CRM one order模型BOR类型支持的对象列表
  6. java.lang.ClassNotFoundException: org.jaxen.JaxenException
  7. python安装教程-Python 3.5安装教程
  8. 安恒赛php_安恒四月赛部分Writeup
  9. 大学计算机实践教程在线阅读,计算机基础实践教程.pdf
  10. 热力地图高德_调用高德地图API(热力图)详解
  11. c语言身份证号码验证
  12. 安装和配置fedora19要做的那些事,超值经验
  13. addrule android用法,RelativeLayout.LayoutParams 使用addRule失效的问题解决办法
  14. 2021年施工员-装饰方向-岗位技能(施工员)考试报名及施工员-装饰方向-岗位技能(施工员)找解析
  15. 如何远程访问 Redis
  16. vscode--vue注释快捷方式
  17. 使用python中PIL库进行切图时候出现了图片全黑
  18. A001 - 基础 - 交换机原理简述
  19. SCORM课程对接线上课程学习平台
  20. html li spry,借助于spry实现Tab面板

热门文章

  1. 强化学习如何真正实现任务自动化?不妨试试「两步走」策略!
  2. 人脸识别技术突飞猛进 为应用领域拓展奠定基础
  3. 腾讯的人工智能大战已然打响!
  4. 多个ERP系统连接一个EWM系统
  5. SAP WM 采购订单收货后LT06上架界面弹出的QM Sample小窗口如何不让其出现?
  6. 2017回顾与2018前瞻:机器学习与人工智能
  7. 诺奖得主克鲁格曼:比特币是庞氏骗局,但不一定很快走向崩溃
  8. 深度解析:国产化软硬件全景梳理
  9. 【工业互联网】全球工业互联网十大最具成长性技术展望(2019-2020年)
  10. 除了芯片 我们还应关注哪些核心技术