如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
提示:
- 1 <= s.length <= 2 * 10^5
- s 仅由可打印的 ASCII 字符组成
解题:
func isPalindrome(s string) bool {
l := len(s)
if l <= 1 {
return true
}
for i, j := 0, l-1; i < j; i++ {
for i < j && trans(s[i]) == 0 {
i++
}
for i < j && trans(s[j]) == 0 {
j--
}
if trans(s[i]) != trans(s[j]) {
return false
}
j--
}
return true
}
func trans(b byte) byte {
if b > 122 {
return 0
}
if b >= 97 {
return b - 32
}
if b > 90 {
return 0
}
if b >= 65 {
return b
}
if b > 57 {
return 0
}
if b >= 48 {
return b
}
return 0
}
官方解答:
1.筛选 + 判断
func isPalindrome(s string) bool {
var sgood, sgoodRev string
for i := range s {
if isalnum(s[i]) {
sgood += string(s[i])
}
}
sgood = strings.ToLower(sgood)
l := len(sgood)
for i := l - 1; i >= 0; i-- {
sgoodRev += string(sgood[i])
}
return sgood == sgoodRev
}
func isalnum(ch byte) bool {
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
}
双指针
func isPalindrome(s string) bool {
var sgood string
for i := 0; i < len(s); i++ {
if isalnum(s[i]) {
sgood += string(s[i])
}
}
n := len(sgood)
sgood = strings.ToLower(sgood)
for i := 0; i < n/2; i++ {
if sgood[i] != sgood[n-1-i] {
return false
}
}
return true
}
func isalnum(ch byte) bool {
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
}
2.在原字符串上直接判断
func isPalindrome(s string) bool {
s = strings.ToLower(s)
left, right := 0, len(s)-1
for left < right {
for left < right && !isalnum(s[left]) {
left++
}
for left < right && !isalnum(s[right]) {
right--
}
if left < right {
if s[left] != s[right] {
return false
}
left++
right--
}
}
return true
}
func isalnum(ch byte) bool {
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
}