回答你的问题:回文 – 是否有可能让我的代码更快?

huangapple go评论79阅读模式
英文:

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 &#39;aaba&#39;, then it can be made into the palindrome &#39;aba&#39; 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 (
    &quot;fmt&quot;
    )

func Palindrome(s string) bool {
    var l int = len(s)

    for i := 0; i &lt; 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 &lt; len(s); i++ {
        if Palindrome(RemoveChar(s, i + 1)) {
            return i
        }
    }

    return -2
}

func main() {
    var s string = &quot;aabaab&quot;
    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 &lt; 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 &lt; 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).

huangapple
  • 本文由 发表于 2014年12月13日 13:49:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/27455983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定