給定一個字符串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; } }
上面就是動態規劃方法,還會持續更新,但願你們關注!!!