题干
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
题解 -- 双指针法
时间复杂度O(n), 空间复杂度O(1)
import (
"fmt"
"strings"
"unicode"
)
// 判断字符是否是数字或者字母,也可以直接判断ascii码范围
func IsDigitOrLetter(ch byte) bool {
return unicode.IsDigit(int32(ch)) || unicode.IsLetter(int32(ch))
}
// 判断字符串是否为回文串
func isPalindrome(s string) bool {
// 因为题目要求回文串大小写不敏感,所以先全部转成小写
s = strings.ToLower(s)
// 双指针,i指向数组开头,j指向数组结尾
var i int
var j int = len(s) - 1
// i和j一起向中间移动
for {
// 跳过那些不是字母或者数字的字符
for !IsDigitOrLetter(s[i]) && i < j {
i++
}
for !IsDigitOrLetter(s[j]) && j > i {
j--
}
// 如果左指针和右指针重合或者左指针在右指针的右边,那么直接退出循环返回true
if i >= j {
break
}
// 如果左右指针对应的字符不相等,则直接返回false
if s[i] != s[j] {
return false
}
i++
j--
}
return true
}
func main() {
s := "A man, a plan, a canal: Panama"
fmt.Println(isPalindrome(s))
s = "race a car"
fmt.Println(isPalindrome(s))
s = " "
fmt.Println(isPalindrome(s))
s = "123 321"
fmt.Println(isPalindrome(s))
s = ".,"
fmt.Println(isPalindrome(s))
}