回文 - 是否有可能使我的代码更快

时间:2014-12-13 05:49:00

标签: performance go

我有一个只有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))
}

2 个答案:

答案 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;检查只需要考虑字符串的中间部分(尚未检查过)。