英文:
Palindrome - Is it possible to make my code faster
问题
我有一个只包含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))
}
请注意,这是你提供的代码的翻译版本,我并不会对其进行任何修改或优化。
英文:
I have an ASCII-only string which is either already a palindrome, or else can be made a palindrome by removing one character. I need to determine whether it's already a palindrome, and if not, I need to find the index of the character that would need to be removed. For example, if the string is 'aaba', then it can be made into the palindrome 'aba' by removing the first character, so I need to return 0.
I have working code, but I am wondering if it is possible to make it faster, because I need to work with many long strings.
Here is my code:
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))
}
答案1
得分: 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
}
英文:
This should be very slightly more efficient than ruakh's solution. You shouldn't have to use isPalindrome() to check that s[i + 1:len(s) - i] is a palindrome because it's quicker to check that s[i:len(s) - i - 1] is not a palindrome. In the solution below, in most cases j won't get very far at all before the function returns.
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
}
答案2
得分: 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
}
它从字符串的两端开始遍历,直到找到一对字节,这对字节在字符串是回文时应该匹配,但实际上不匹配。然后它知道它将返回这两个字节中的一个的索引,因此它只需要执行一次“这是一个回文吗?”的检查;而且它不需要使用RemoveChar函数,因为“这是一个回文吗?”的检查只需要考虑字符串的中间部分(尚未被检查过的部分)。
英文:
Here is a much more efficient approach:
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
}
It just proceeds from the ends of the string until it finds a pair of bytes that should match, if the string were a palindrome, but that do not. It then knows that it will return the index of one of these two bytes, so it only needs to perform one "is this a palindrome?" check; and it doesn't need to use the RemoveChar function, since the "is this a palindrome?" check only needs to consider the middle portion of the string (that hasn't already been examined).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论