将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
这道题目刚开始真是完全没看懂,感觉更像是倒N字形,看明白了之后发现确实按照字符的排序还是Z字形。但其实什么形状的并不是很重要,题目给出的排列是很偏图形化的,然而最后需要我们输出的却是一条字符串,所以可以暂时忽略掉这个图形化的问题。也正是看了这个图,我第一时间想到了用二维数组来写这道题,最后看了别的大佬的答案才有所悔悟,
从表面上看这道题是一个Z字形的排列,实际上它并没有在空间上实际形成Z字形,通过最后的结论来看,只是将字符串从上往下再从下往上如此反复的排列,再从横向取新字符串。
以下是我的理解:
numRows
的字符串数组。这里犯了一个错,python中一维数组的声明需要用到类似[""]*numRows
的声明,不然会出现超出列表长度的问题。s
从sol[0]
到sol[numRows-1]
一直往下输入,直到sol[numRows-1]
,这时候将输入的方向颠倒。这里用到了一个增量inc
,本身为1,从0到numRows-1时逐一增加,直到numRows-1开始inc*=-1
使得逐一递减直到0,如此往复。sol[0]
到sol[numRows-1]
加到一个字符串就好了整个代码里面最核心的就是python字符串相加的这个功能,可以很简洁地用+=
来实现。
class Solution:
def convert(self, s, numRows):
index=0
sol=[""]*numRows
#sol=[] #错误
inc=1
final=""
for i in range(len(s)):
sol[index]+=s[i]
if numRows>1:
index+=inc
if index== 0 or index==numRows-1:
inc*=-1
for j in range(numRows):
final+=sol[j]
return final
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
难得看到自己马上做完了一道,果然还是道Easy难度题:
class Solution:
def reverse(self, x: int) -> int:
flag=1
if x<0:
x*=-1
flag=-1
s=str(x)[::-1]
y=int(s)*flag
if -2**31<=y<=2**31-1:
return y
else:
return 0
这道题比较纳闷的是,当我直接用最大值2147483647与最小值-2147483648替换两个表达式时,反而用了更久的运行时间,我也不知道为什么。
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
曾经用的是枚举所有情况分类讨论,太复杂了,这也是为什么这道题被很多人骂,下面是我之前的解答,我自己都不想再去看了:
class Solution:
def myAtoi(self, strr) -> int:
nflag=False
sflag=False
strr_new=""
for i in range(len(strr)):
if strr[i]==" " and nflag==False:
continue
elif (strr[i]=="+" or strr[i]=="-") and nflag==False:
nflag=True
strr_new+=strr[i]
elif strr[i]=="0" or strr[i]=="1" or strr[i]=="2" or strr[i]=="3" or strr[i]=="4" or strr[i]=="5" or strr[i]=="6" or strr[i]=="7" or strr[i]=="8" or strr[i]=="9":
nflag=True
strr_new+=strr[i]
else:
sflag=True
if nflag==True:
break
if sflag==True and nflag==False:
return 0
if strr_new=='+' or strr_new=='-' or strr_new=='':
return 0
if int(strr_new)<-2**31:
return -2**31
elif int(strr_new)>2**31-1:
return 2**31-1
else:
return int(strr_new)
这次看到了一个大佬的一行解决这道题,感觉太强了,得学一下:
class Solution:
def myAtoi(self, s: str) -> int:
return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
作者:QQqun902025048
链接:https://leetcode-cn.com/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
^:匹配字符串开头
[+-]:代表一个+字符或-字符
?:前面一个字符可有可无
\d:一个数字
+:前面一个字符的一个或多个
\D:一个非数字字符
*:前面一个字符的0个或多个
作者:QQqun902025048
链接:https://leetcode-cn.com/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
正则表达式在这之前完全没有接触过,我看起来也很困难,这个是另外一个大佬拆开分析的这段语句,我觉得对初学者来说更实用一点:
import re
class Solution:
def myAtoi(self, str: str) -> int:
INT_MAX = 2147483647
INT_MIN = -2147483648
str = str.lstrip() #清除左边多余的空格
num_re = re.compile(r'^[\+\-]?\d+') #设置正则规则
num = num_re.findall(str) #查找匹配的内容
num = int(*num) #由于返回的是个列表,解包并且转换成整数
return max(min(num,INT_MAX),INT_MIN) #返回值
我学习一下正则表达式吧,可以省去很多if else。
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
这道题相信经过Q5最长回文子串的洗礼已经不算什么了,一行搞定:
class Solution:
def isPalindrome(self, x: int) -> bool:
return True if str(x)[:]==str(x)[::-1] else False
以后回来填坑
python中的一维与二维数组声明:
a = [None] * n
创建一个初值为None的长度为n的列表a,None只是一种初值也可换成其他的初值。 比如Q6中创建可以用sol=[""]*numRows
a = [[X for col in range(m)] for row in range(n)]
创建一个n*m的二维矩阵a(横向n纵向m),每个初值都是X
不要总想着用分类讨论(写一堆if elif)写边界问题,换个思维想一想是否可以通过一些变量来取消分类讨论。Q6中可以当到达边界时,可以让增量inc*=-1
来控制在边界的转换问题。
正则表达式可以解决一些需要寻找以及处理特殊字符的问题,今天好好学习一下这些语句