因此,我正在迅速写一些在线评判。
以下是问题:最长的回文子串
给定字符串S,找到S中最长的回文子字符串。您可以假设S的最大长度为1000,并且存在一个唯一最长的回文子字符串。
所以我使用dp在swift中解决它:
class Solution {
func longestPalindrome(s: String) -> String {
var hash = Array(count: s.characters.count, repeatedValue: Array(count: s.characters.count, repeatedValue: false))
for i in 0 ..< s.characters.count {
hash[i][i] = true
}
var maxStart = 0
var maxEnd = 0
var maxCount = 1
for i in 1.stride(through: s.characters.count - 1, by: 1) {
for j in 0 ..< s.characters.count - 1 {
if j + i < s.characters.count {
if isValidPalindrome(j, j + i, s, hash) {
hash[j][j + i] = true
if maxCount < i + 1 {
maxCount = i
maxStart = j
maxEnd = j + i
}
}
}
else {
break
}
}
}
// construct max palindrome string, swift string is so dummy
var str = ""
for i in maxStart...maxEnd {
let index = s.characters.startIndex.advancedBy(i)
str += String(s.characters[index])
}
return str
}
func isValidPalindrome(start: Int, _ end: Int, _ s: String, _ hash: [[Bool]]) -> Bool {
// end <= s's length - 1
let startIndex = s.startIndex.advancedBy(start)
let endIdnex = s.startIndex.advancedBy(end)
if end - start == 1 {
return s[startIndex] == s[endIdnex]
}
else {
let left = start + 1
let right = end - 1
return s[startIndex] == s[endIdnex] && hash[left][right]
}
}
}
我认为这是正确的,但是当我提交时,总是超出长字符串的时间,如:
"kyyrjtdplseovzwjkykrjwhxquwxsfsorjiumvxjhjmgeueafubtonhlerrgsgohfosqssmizcuqryqomsipovhhodpfyudtusjhonlqabhxfahfcjqxyckycstcqwxvicwkjeuboerkmjshfgiglceycmycadpnvoeaurqatesivajoqdilynbcihnidbizwkuaoegmytopzdmvvoewvhebqzskseeubnretjgnmyjwwgcooytfojeuzcuyhsznbcaiqpwcyusyyywqmmvqzvvceylnuwcbxybhqpvjumzomnabrjgcfaabqmiotlfojnyuolostmtacbwmwlqdfkbfikusuqtupdwdrjwqmuudbcvtpieiwteqbeyfyqejglmxofdjksqmzeugwvuniaxdrunyunnqpbnfbgqemvamaxuhjbyzqmhalrprhnindrkbopwbwsjeqrmyqipnqvjqzpjalqyfvaavyhytetllzupxjwozdfpmjhjlrnitnjgapzrakcqahaqetwllaaiadalmxgvpawqpgecojxfvcgxsbrldktufdrogkogbltcezflyctklpqrjymqzyzmtlssnavzcquytcskcnjzzrytsvawkavzboncxlhqfiofuohehaygxidxsofhmhzygklliovnwqbwwiiyarxtoihvjkdrzqsnmhdtdlpckuayhtfyirnhkrhbrwkdymjrjklonyggqnxhfvtkqxoicakzsxmgczpwhpkzcntkcwhkdkxvfnjbvjjoumczjyvdgkfukfuldolqnauvoyhoheoqvpwoisniv"
我可以在一段时间后得到正确的结果qahaq
,我想知道为什么它这么慢。如果我用其他语言写,不是那么糟糕。
我怀疑API s.startIndex.advancedBy(start)
正在导致它,但我检查了文档,没有时间复杂性,没有其他方法将int转换为startIndex类型?
任何取代advancedBy的想法?提前谢谢。
答案 0 :(得分:0)
对于那些有同样问题的人:我将swift String转换为Array,它变得更快。
我还查看了关于advancedBy实现的Swift源代码,这是一个O(n)opreation,这就是为什么它很慢。
对于实施感兴趣的人,请查看https://github.com/apple/swift/blob/8e12008d2b34a605f8766310f53d5668f3d50955/stdlib/public/core/Index.swift
你会看到advancedBy只是多个后继者():
@warn_unused_result
public func advanced(by n: Distance) -> Self {
return self._advanceForward(n)
}
/// Do not use this method directly; call advanced(by: n) instead.
@_transparent
@warn_unused_result
internal func _advanceForward(_ n: Distance) -> Self {
_precondition(n >= 0,
"Only BidirectionalIndex can be advanced by a negative amount")
var p = self
var i : Distance = 0
while i != n {
p._successorInPlace()
i += 1
}
return p
}
答案 1 :(得分:0)
这应该可以解决问题。在实施之前,我建议您查看一些解释,例如这个人。 https://www.youtube.com/watch?v=obBdxeCx_Qs。虽然我相信他的视频有点用处,但我并不隶属于他。
func longestPalindrome(_ s: String) -> String {
var charArray = [Character("$"), Character("#")]
for i in s.characters {
charArray += [i, Character("#")]
}
charArray += [Character("@")]
var mir = 0, c = 0, r = 0, longestPalindromeIndex = 0, longestPalindromeLength = 0, ss = "", returnString = ""
var p = [Int]()
//MARK: For loop
for i in 0...(charArray.count - 1) {
p += [0, 0]
mir = 2 * c - i
if i < r {
p[i] = min(r - i, p[mir])
}
if i - (1 + p[i]) >= 0 && i + (1 + p[i]) < charArray.count - 1 {
while charArray[i + (1 + p[i])] == charArray[i - (1 + p[i])] {
p[i] += 1
}
}
if p[i] > longestPalindromeLength {
longestPalindromeIndex = i
longestPalindromeLength = p[i]
}
if i + p[i] > r {
c = i
r = i + p[i]
}
}//for loop
for i in Array(charArray[(longestPalindromeIndex - longestPalindromeLength)...(longestPalindromeIndex + longestPalindromeLength)]) {
ss = String(i)
if ss != "#" && ss != "$" && ss != "@" {
returnString += ss
}
}
return returnString
}//func