【2017.12.4】5.Longest Palindromic Substring最长回文子串

来源:互联网 发布:mikumikudance mac版 编辑:程序博客网 时间:2024/06/10 05:45

在之前的算法那本书有写过,这次重新写一篇

After all,we do not inherit the earth from ancestors.We borrow it form our children.

5.1 Palindome 回文

回文是在两个方向读取相同的字符串的意思

5.2 Dynamic Programming动态规划

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。
20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划

5.2.1 动态规划一般可分为线性动规,区域动规,树形动规,背包动规四类。

举例:
- 线性动规:拦截导弹,合唱队形,挖地雷,建学校,剑客决斗等;
- 区域动规:石子合并, 加分二叉树,统计单词个数,炮兵布阵等;
- 树形动规:贪吃的九头龙,二分查找树,聚会的欢乐,数字三角形等;
- 背包问题:01背包问题,完全背包问题,分组背包问题,二维背包,装箱问题,挤牛奶(同济ACM第1132题)等;

5.2.2 应用实例:

最短路径问题 ,项目管理,网络流优化等;

5.2.3 基本结构:

多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化问题的方法为动态规划方法。

5.2.4 基本模型:

根据上例分析和动态规划的基本概念,可以得到动态规划的基本模型如下:

(1)确定问题的决策对象。(2)对决策过程划分阶段。 (3)对各阶段确定状态变量。 (4)根据状态变量确定费用函数和目标函数。 (5)建立各阶段状态变量的转移过程,确定状态转移方程。

5.2.5 状态转移方程的一般形式:

    一般形式: **U**:状态; **X**:策略    顺推:**f[Uk]=opt{f[Uk-1]+L[Uk-1,Xk-1]}**    其中, **L[Uk-1,Xk-1]**: 状态Uk-1通过策略Xk-1到达状态Uk 的费用     初始:**f[U1]**;    结果:**f[Un]**。    倒推:**f[Uk]=opt{f[Uk+1]+L[Uk,Xk]}**    **L[Uk,Xk]**: 状态Uk通过策略Xk到达状态Uk+1 的费用    初始:**f[Un]**;    结果:**f(U1)**

5.2.6 适用条件

任何思想方法都有一定的局限性,超出了特定条件,它就失去了作用。同样,动态规划也并不是万能的。适用动态规划的问题必须满足最优化原理和无后效性。

  • 最优化原理(最优子结构性质)
    最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。

  • 无后效性
    将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。

  • 3.子问题的重叠性
    动态规划将原来具有指数级时间复杂度的搜索算法改进成了具有多项式时间复杂度的算法。其中的关键在于解决冗余,这是动态规划算法的根本目的。

5.5.6 valid 有效的

5.5.7 indice 索引

5.5.8 non-trivial algorithm 不平凡的算法

平凡问题通常指规模小,或简单,或计算复杂性低的问题;不平凡问题则是指规模大,或复杂困难,或计算复杂性高的问题。

———————————— 我是分割线 ————————————————————

5.Longest Palindromic Substring最长回文子串

题目:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: “babad”

Output: “bab”

Note: “aba” is also a valid answer.

Example:

Input: “cbbd”

Output: “bb”

Summary

This article is for intermediate readers. It introduces the following ideas:** Palindrome(回文), Dynamic Programming (动态规划)and String Manipulation(字符串操作). Make sure you understand what a palindrome means. **A palindrome is a string which reads the same in both directions. For example,“aba” is a palindome,“abc” is not.

Solution:

——————– 分割线啦啦啦啦啦 ———————-

Approach #1 (Longest Common Substring) [Accepted]

Common mistake(常见的错误)

Some people will be tempted to come up with a quick solution, which is unfortunately flawed (however can be corrected easily):

Reverse S and become S′​​ . Find the longest common substring between S and S​′​​ , which must also be the longest palindromic substring.

This seemed to work, let’s see some examples below.

For example, S = “caba”, S’ =”abac”.

The longest common substring between S and S′ is “aba”, which is the answer.

Let’s try another example: S=”abacdfgdcaba”, S​’=”abacdgfdcaba”.

The longest common substring between S and S​′​​ is “abacd”. Clearly this is not a valid palindrome.(有效的回文)

Algorithm:

We could see that the longest common substring method fails when there exists a reversed copy of a non-palindromic substring in some other part of S.

To rectify(纠正) this, each time we find a longest common substring candidate(候选), we check if the substring’s indices are the same as the reversed substring’s original indices(检查子串的索引是否与反向子串的原始索引相同). If it is, then we attempt to update the longest palindrome found so far; if not, we skip this and find the next candidate.

This gives us an O(n^2) Dynamic Programming solution which uses O(n^2) space (could be improved to use O(n) space).

———————分割线啦啦啦啦啦———————————–

Approach #2 (Brute Force)(暴力) [Time Limit Exceeded]

The obvious brute force solution is to pick all possible starting and ending positions for a substring, and verify if it is a palindrome.

挑选一个子串的所有可能的开始和结束的位置

Complexity Analysis:

  • Time complexity : O(n^3)​​.
    Assume that n is the length of the input string, there are a total of (​ ​n 2​​ )=​​n(n−1)/2 such substrings (excluding the trivial solution where a character itself is a palindrome). Since verifying each substring takes O(n) time, the run time complexity is O(n​^3).
  • Space complexity : O(1).

———————分割线啦啦啦啦啦———————————–

Approach #3 (Dynamic Programming) [Accepted]

To improve over the brute force solution, we first observe how we can avoid unnecessary re-computation while validating palindromes. (当在验证回文的时候避免不必要的计算)Consider the case “ababa”. If we already knew that “bab” is a palindrome, it is obvious that ”ababa” must be a palindrome since the two left and right end letters are the same.

这里写图片描述

这里产生了一份直接的DP解决方案,我们首先初始化一个和两个子母的回文串,并找到所有三个字母的回文串工作。

Could you improve the above space complexity further and how?

———————分割线啦啦啦啦啦———————————–

Approach #4 (Expand Around Center) [Accepted]

In fact, we could solve it in O(n^2) time using only constant space.

We observe that a palindrome mirrors around its center. Therefore, a palindrome can be expanded from its center, and there are only 2n−1 such centers.

You might be asking why there are 2n−1 but not n centers? The reason is the center of a palindrome can be in between two letters. Such palindromes have even number of letters (such as “abba”) and its center are between the two ‘b’ s.

class Solution {    public String longestPalindrome(String s) {        //使 DP 算法        int start = 0 , end = 0 ;        for (int i = 0; i < s.length() ; i++){            //偶数的情况            int len1 = expandAroundCenter(s, i, i);            //奇数的情况            int len2 = expandAroundCenter(s, i, i+1);            //取最大值            int len = Math.max(len1 , len2);            if(len > end - start){                start = i-(len-1)/2;                end = i+len/2;            }        }        return s.substring(start,end+1);    }    //从中心向外边扩展    private int expandAroundCenter(String s, int left , int right){        int L = left, R = right;        while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)){            L--;            R++;        }        return R-L-1;     }}

Complexity Analysis

  • Time complexity : O(n^2).
    Since expanding a palindrome around its center could take O(n) time, the overall complexity(整体的复杂度) is** O(n^2)**.
  • Space complexity : O(1).

———————-分割线啦啦啦啦啦———————————–

Approach #5 (Manacher’s Algorithm) [Accepted]

There is even an O(n) algorithm called Manacher’s algorithm, explained here in detail .
However, it is a non-trivial algorithm(不平凡的算法), and no one expects you to come up with this algorithm in a 45 minutes coding session. But, please go ahead and understand it, I promise it will be a lot of fun.

———————分割线啦啦啦啦啦———————————–

友情链接:

leecode-解答

百度-动态规划

CSDN-教你彻底学会动态规划——入门篇(还没看)

知乎-什么是动态规划?动态规划的意义是什么?

阅读全文
0 0