英文:
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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论