文章目录
数据的预处理
我认为本道题主要是对数据做处理
第一步:Python 字符串大小写转换
这里使用了lower()函数
s = "A man,a plan好, +a canal: Panama"
b=s.lower()
b
输出结果
'a man,a plan好, +a canal: panama'
第二步:只保留字母和数字(三个做法)
1. filter()函数的缺陷
a="".join(filter(str.isalnum, b))
a
输出结果
'amanaplan好acanalpanama'
我们明显的看出,虽然保留了字母和数字,但是它不会剔除汉字,不满足题目要求
2. 正则表达
#字符串只保留英文和数字
m= re.sub(u"([^\u0041-\u005a\u0061-\u007a\u0030-\u0039])", "", b)
输出结果
'amanaplanacanalpanama'
显然满足题目要求
3. isalnum()函数
官方给出的是isalnum()函数,但是这个我事先不是很了解,但是搜索了之后发现挺香的
isalnum()的详细介绍
这个函数的主要作用就是判断字符是否为字母或数字,如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
当你遇到一个非字母或数字的直接跳过不就OK了!
m = "".join(ch.lower() for ch in s if ch.isalnum())
这句话就是,遍历字符串s,判断s的每一个字符ch是否为数字或英文,如果是则换为小写,加入到m里面,挺好玩。
后面最小空间的时候还有用处
while left < right and not s[left].isalnum():
left += 1
这句话就是,如果s[left].isalnum()为True,则跳过继续,当s[left].isalnum()为非数字或英文时,则为not False,则指针后移
代码展示
自己的写法(双指针)
这是一开始我自己的写法
class Solution:
def isPalindrome(self, s: str) -> bool:
s=s.lower()
s= re.sub(u"([^\u0041-\u005a\u0061-\u007a\u0030-\u0039])", "", s)
if(s==""):
return True
Len=len(s)
left=0
right=Len-1
mid=(int)(Len/2)
for i in range(mid):
if(s[left]!=s[right]):
return False
else:
left+=1
right-=1
return True
逆序输出法–只有三行
这是我看了一眼参考答案,直接惊呆了老铁,它直接使用数组逆序输出,玩阴的呜呜呜
class Solution:
def isPalindrome(self, s: str) -> bool:
s=s.lower()
s= re.sub(u"([^\u0041-\u005a\u0061-\u007a\u0030-\u0039])", "", s)
return s==s[::-1]
最省空间的方法–空间复杂度O(1)
这个我没验证,它主要的想法也是双指针,但是它最厉害的是它在原有的基础上改变的字符串,使得空间复杂度变为O(1)
class Solution:
def isPalindrome(self, s: str) -> bool:
n = len(s)
left, right = 0, n - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if left < right:
if s[left].lower() != s[right].lower():
return False
left, right = left + 1, right - 1
return True
Over! 第一次写这种Markdown形式的,好累,哈哈哈