给定一个字符串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; } }
上面就是动态规划方法,还会持续更新,但愿你们关注!!!