最長迴文子串--動態規劃

給定一個字符串s,找到s中最長的迴文子串. 你能夠假設 s 的最大長度爲1000.函數

示例1spa

輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。

示例2code

輸入: "cbbd"
輸出: "bb"

 

解法一: 暴力解法blog

根據迴文子串的定義,枚舉全部長度大於等於2的子串,以此判斷它們是不是迴文.在具體實現中,能夠只針對大於「當前獲得的最長迴文子串長度」的子串進行迴文子串.下面咱們用暴力解法,列舉出全部的,可是時間超出了限制,可是仍是將這種方式貼出來字符串

import Foundation //想要導入,不然string無subString方法
func longestPalindrome(_ s: String) -> String {
    guard s.count > 0 else {return ""}
    if s.count == 1 {return s}
    var maxLen: Int = 1
    
    let range = NSRange(location: 0, length: 1)
    let result = (s as NSString).substring(with: range)
    var resultStr = result as String
    
    for i in 0..<s.count - 1 {
        for j in i + 1..<s.count {
            if j - i + 1 > maxLen && valid(s, left1: i, right1: j) {
                maxLen = j - i + 1
                let range = NSRange(location: i, length: maxLen)
                let result = (s as NSString).substring(with: range)
                resultStr = result
            }
        }
    }
    return resultStr
}
//判斷迴文
func valid(_ s: String, left1: Int, right1: Int) -> Bool {
    let strArr = Array(s)
    var left: Int = left1
    var right: Int = right1
    while left < right {
        if strArr[left] != strArr[right]  {
            return false
        }
        left = left + 1
        right -= 1
    }
    return true
}

而後在leetCode上提交,可是時間超過了限制,給出的結果以下:string

 

 

解法二: 動態規劃it

解法一的時間複雜度太高,在leetCode上並不能AC.下面有改進方法io

首先咱們定義P(i,j) 以下 class

接下來import

P( i , j ) = (P( i + 1,  j - 1 )&& S[ i ] == S[ j ])

因此若是咱們知道了P( i, j )的狀況,不須要調用判斷迴文串的函數了,只須要知道P( i + 1,  j - 1 )的狀況就能夠了,這樣時間複雜度就會減小了O(n), 所以咱們採起動態規劃的方案,用空間換取時間,把已經求出來的P(i, j)存儲起來.

若是S[i + 1, j -1]是迴文串, 那麼只要S[i] == S[j] 就能夠肯定S[i, j]是迴文串.

求長度爲1和長度爲2的P(i,j)時不能用上邊的公式,由於帶上去,發現越界,因此要分兩種狀況考慮.

因此咱們先初始化長度爲1的迴文串的P(i,j),利用上面的提出的公式,而後兩邊向外各擴充一個字符,長度爲3, 5的,全部的長度就求出來了.

同理, 初始化長度爲2的迴文串,利用公式,獲得了長度爲4, 6的全部偶數長度就都求出來了.

代碼以下:

class Solution {
    public String longestPalindrome(String s) {
    int length = s.length();
    if (length == 1){return s;}
    boolean[][] P = new boolean[length][length];
    int maxLen = 0;
    String maxPal = "";
    for (int i = 1; i <= length; i++) //遍歷全部的長度
    for (int j = 0; j < length; j++) {
        int k = i + j - 1;
        if (k >= length) //下標已經越界,結束本次循環
        break;
        P[j][k] = (i == 1 || i == 2 || P[j + 1][k - 1]) && s.charAt(j) == s.charAt(k); //長度爲 1 和 2 的單獨判斷下
        if (P[j][k] && k > maxLen) {
            maxPal = s.substring(j, k + 1);
        }
    }
    return maxPal;
}
}

上面就是動態規劃方法,還會持續更新,但願你們關注!!!

相關文章
相關標籤/搜索