Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AlexanderBollbach/82df9903fd605e5b32934c91fe404af2 to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/82df9903fd605e5b32934c91fe404af2 to your computer and use it in GitHub Desktop.
class Solution {
func longestPalindrome(_ s: String) -> String {
var stepper = 0
if s.count == 1 { return String(s.first!) }
if s.count == 2 {
if s.last == s.first {
return s
} else {
return String(s.first!)
}
}
var candidates = [Candidate]()
var acc = ""
var finished = Set<Candidate>()
var runningLength = 0
for c in s.enumerated() {
let thisChar = c.element
let thisIndex = c.offset
if runningLength > s.count - thisIndex { continue }
for candidate in candidates {
stepper += 1
let isNext = thisIndex == candidate.index + 1 // this index is either current index or subsequent (should it ever be current? -- ==)
let matchesLast = thisChar == candidate.string.last
// must only match if isNext
let matchesSecondLast = String(thisChar) == candidate.string.pinultimate() && isNext
// add both even / odd
if matchesLast && matchesSecondLast {
let str = candidate.string
// even subsumes odd
candidate.string = String(candidate.string.dropLast().dropLast())
candidate.isOdd = true
let even = Candidate(index: candidate.index, string: str, isOdd: false)
even.string = String(even.string.dropLast())
candidates.append(even)
}
else if matchesSecondLast // odd
{
candidate.string = String(candidate.string.dropLast().dropLast())
candidate.isOdd = true
}
else if matchesLast // even
{
candidate.string = String(candidate.string.dropLast())
} else {
if let i = candidates.index(of: candidate) { candidates.remove(at: i) }
if !isNext && candidate.wasAltered { finished.insert(candidate) }
}
}
candidates.sort(by: { $0.length > $1.length })
candidates = Array(candidates.prefix(3))
acc.append(thisChar)
let candidate = Candidate(index: thisIndex, string: acc, isOdd: false)
candidates.append(candidate)
}
// trim - last indicis
for candidate in candidates {
if (candidate.index + 1) > candidate.string.count {
finished.insert(candidate)
}
}
let ss = finished.map {
foo in foo.extract(s: s)
}
let r = ss.reduce("") { (p, n) -> String in
return n.count > p.count ? n : p
}
if r.isEmpty && !s.isEmpty {
return String(s.first!)
}
// print(stepper)
return r
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment