Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AlexanderBollbach/c2ed22d2085040c5c90eb894a42839fa to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/c2ed22d2085040c5c90eb894a42839fa to your computer and use it in GitHub Desktop.
class Solution {
var perf = 0
func longestPalindrome(_ s: String) -> String {
var cache = [Range: String]()
func longest(range: Range) -> String {
if range.count == 1 {
return s.from(range: range)
}
if let c = cache[range] {
return c
}
let rangeIsOdd = range.count % 2 != 0
let mid = range.start + (range.end - range.start) / 2
if rangeIsOdd {
perf += 1
let leftMiddle = longest(range: Range(start: range.start, end: mid))
let rightMiddle = longest(range: Range(start: mid, end: range.end))
if leftMiddle == rightMiddle {
var str = s.from(range: range)
if leftMiddle == "" || rightMiddle == "" {
str = ""
}
cache[range] = str
return str
}
} else {
perf += 1
let left = longest(range: Range(start: range.start, end: mid))
let right = longest(range: Range(start: mid + 1, end: range.end))
if left == right {
var str = s.from(range: range)
if left == "" || right == "" {
str = ""
}
cache[range] = str
return str
}
}
// middle out
var leftIndex: Int
var rightIndex: Int
if rangeIsOdd {
leftIndex = mid
rightIndex = mid
} else {
leftIndex = mid
rightIndex = mid + 1
}
var left = s.safeStr(i: leftIndex)
var right = s.safeStr(i: rightIndex)
var fullyExpanded = false
while rightIndex <= range.end && leftIndex >= range.start {
perf += 1
left = s.safeStr(i: leftIndex)
right = s.safeStr(i: rightIndex)
if left == right {
let currRange = Range(start: leftIndex, end: rightIndex)
let str = s.from(range: currRange)
cache[currRange] = str
if leftIndex == range.start && rightIndex == range.end {
fullyExpanded = true
}
} else {
break
}
leftIndex -= 1
rightIndex += 1
}
if fullyExpanded {
return s.from(range: range)
} else {
return ""
}
}
for i in 0..<s.count {
let range = Range(start: 0, end: i)
let p = longest(range: range)
cache[range] = p
}
for i in 0..<s.count {
let range = Range(start: i, end: s.count - 1)
let p = longest(range: range)
cache[range] = p
}
let final = cache.reduce("") { a,b in
return b.value.count > a.count ? b.value : a
}
return final
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment