Description
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
For example,
“A man, a plan, a canal: Panama” is a palindrome.
“race a car” is not a palindrome.
Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.
For the purpose of this problem, we define empty string as valid palindrome.
Code
class Solution(object):
def isPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
start, end = 0, len(s) - 1
while start <= end:
while start <= end and not self.checkValid(s[start]):
start += 1
while start <= end and not self.checkValid(s[end]):
end -= 1
if start <= end and self.checkNotSame(ord(s[start]), ord(s[end])) and self.checkNotSame(ord(s[end]), ord(s[start])):
return False
start, end = start + 1, end - 1
return True
def checkValid(self, alpha):
return (alpha >= '0' and alpha <= '9') or (alpha >= 'a' and alpha <= 'z') or (alpha >= 'A' and alpha <= 'Z')
def checkNotSame(self, a, b):
if (a >= 48 and a <= 57) or (b >= 48 and b <= 57):
return a != b
else:
return a != b and a + 32 != b
里面有个小坑,当判断小写字母是否与大写字母相等时,偷懒写了个加32,结果测试用例里故意出了个”0P”这俩ascii刚好也相差32,恶意满满呀。于是得判断下a, b是否都为字母先。
写完后看了下别人的代码,原来python自带有isalnum()函数,就是用于判断是否字母和数字的…而且关于大小写的判断,可以直接将字符统一为大写或者小写就好了…所以精简的代码应该如下:
Code
class Solution(object):
def isPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
start, end = 0, len(s) - 1
while start < end:
while start < end and not s[start].isalnum():
start += 1
while start < end and not s[end].isalnum():
end -= 1
if s[start].lower() != s[end].lower():
return False
start, end = start + 1, end - 1
return True
注意最外层的while循环条件可以改为小于号,等号可以去掉,因为此时当start == end时肯定字符也相等。同时里面的两个while也应该把等号去掉,如果加上了等号,会造成再次进循环,导致start > end(比如“.,”该用例),则不得不在最后一个if的时候还判断start <= end,造成冗余。
Conclusion
题目很简单,主要学习函数和小细节。