我有一个只有ASCII的字符串,它已经是一个回文,或者可以通过删除一个字符使其成为回文。我需要确定它是否已经是回文,如果没有,我需要找到需要删除的字符的索引。例如,如果字符串为'aaba'
,则可以通过删除第一个字符将其设置为回文'aba'
,因此我需要返回0
。
我有工作代码,但我想知道是否可以加快速度,因为我需要使用很多长字符串。
这是我的代码:
package main
import (
"fmt"
)
func Palindrome(s string) bool {
var l int = len(s)
for i := 0; i < l / 2; i++ {
if s[i] != s[l - 1 - i] {
return false;
}
}
return true
}
func RemoveChar(s string, idx int) string {
return s[0:idx-1] + s[idx:len(s)]
}
func findIdx(s string) int {
if Palindrome(s) {
return -1
}
for i := 0; i < len(s); i++ {
if Palindrome(RemoveChar(s, i + 1)) {
return i
}
}
return -2
}
func main() {
var s string = "aabaab"
fmt.Println(findIdx(s))
}
答案 0 :(得分:3)
这应该比ruakh的解决方案更有效。您不应该使用isPalindrome()来检查s[i + 1:len(s) - i]
是否为回文,因为检查s[i:len(s) - i - 1]
不回文是否更快。在下面的解决方案中,在大多数情况下,j在函数返回之前根本不会走得太远。
func findIdx(s string) int {
var n int = len(s)
for i := 0; i < n / 2; i++ {
if s[i] != s[n - i - 1] {
for j := 0; ;j++ {
if s[i + j] != s[n - 2 - i - j] {
return i;
}
if s[i + j + 1] != s[n - 1 - i - j] {
return n - 1 - i;
}
}
}
}
return -1
}
答案 1 :(得分:1)
这是一种更有效的方法:
func findIdx(s string) int {
for i := 0; i < len(s) / 2; i++ {
if s[i] != s[len(s) - i - 1] {
if isPalindrome(s[i+1:len(s)-i]) {
return i
} else {
return len(s) - i - 1
}
}
}
return -1
}
它只是从字符串的末尾开始,直到它找到一对应匹配的字节,如果字符串是回文,但事实并非如此。然后它知道它将返回这两个字节之一的索引,所以它只需要执行一个&#34;这是一个回文吗?&#34;校验;并且它不需要使用RemoveChar
函数,因为&#34;这是一个回文?&#34;检查只需要考虑字符串的中间部分(尚未检查过)。