携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情 。如果哪里写的不对,请大家评论批评。
希望往后的日子,可以每天坚持一个算法,最近发现一个有意思的事情,LeetCode中等难度的题,也不简单,暴力算法固然能解决问题,但是从时间复杂度和空间复杂度上肯定达不到要求。
最长回文子
题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2
输入: s = "cbbd"
输出: "bb"
分析
中心扩散法(双指针)
为什么会是双指针的?
在回文有两种情况
一种是121这种回文奇数长度的回文,假设指针是i,判断回文就需要i-1==i+1来依次寻找
另一种是1221这种偶数的回文,这种就需要i和i+1两个指针,先判断i==i+1然后再判断i-1==i+1+1依次寻找
看图之后你会发现,其实最后都是需要两个指针,向外扩散去寻找是否相等,奇数如果想和偶数一样先判断是否相等,其实可以先和自身对比一下,伪代码:
//奇数
if (list[i] == list[i]){
L = i - 1
R = i + 1
}
// 偶数
if (list[i] == list[i+1]){
L = i - 1
R = i + 1
}
简单图解
- 奇数寻找
- 偶数寻找
代码
双指针
class Solution {
func longestPalindrome(_ s: String) -> String {
if s.isEmpty {
return ""
}
var L = 0
var R = 0
let chars = Array(s)
for (i, _) in chars.enumerated() {
let unevenL = palindrome(chars, i, i)
let evenL = palindrome(chars, i, i+1)
let MaxLen = max(unevenL, evenL)
if MaxLen > R - L + 1 {
L = i - (MaxLen - 1)/2
R = i + MaxLen/2
}
}
return String(chars[L...R])
}
func palindrome(_ s: [Character], _ l: Int, _ r: Int) -> Int {
var L = l
var R = r
while L >= 0 && R < s.count && s[L] == s[R] {
L -= 1
R += 1
}
return R - L - 1
}
}
class Solution {
func longestPalindrome(_ s: String) -> String {
let chars = Array<Character>(s)
let length = chars.count
guard length > 0 else {
return ""
}
//创建一个,元素值重复,个数固定的数组
var isPalidromeMatrix = Array(repeating: Array(repeating: false, count : length), count : length)
var maxLength = 0
var maxStartIndex = 0
for palidromeLength in 1 ... length {
for startIndex in 0 ... length - palidromeLength {
let endIndex = startIndex + palidromeLength - 1
var isPalidrome = false
if palidromeLength == 1 {
isPalidrome = true
} else if palidromeLength == 2 {
isPalidrome = chars[startIndex] == chars[endIndex]
} else {
isPalidrome = chars[startIndex] == chars[endIndex] && isPalidromeMatrix[startIndex + 1][endIndex - 1]
}
if isPalidrome {
isPalidromeMatrix[startIndex][endIndex] = true
if palidromeLength > maxLength {
maxStartIndex = startIndex
maxLength = palidromeLength
}
}
}
}
return String(chars[maxStartIndex...maxStartIndex + maxLength - 1])
}
}