Python每日一练-----Z字形变换
☀(day45:C3)
目录
📝题目:
🚩题目分析:
💡解题思路:
🌈代码实现
✏代码注释
📝题目:
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"
。
请你实现这个将字符串进行指定行数变换的函数:
⭐示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
⭐示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
⭐示例 3:
输入:s = "A", numRows = 1
输出:"A"
🚩题目分析:
题目要求我们将给出的字符串排成Z字形,但我觉得N字形更贴切一些。排成N字形后从左到右一行一行读取每个字符组成新字符,新字符长度等于原字符长度。
💡解题思路:
题目还是中等题,不用像得过于复杂去找从原字符中读取新字符得规律,也可以不用二维数组储存s得字符构成N字形的形状。
通过观察我们可以直到,numRows既是N字形的行数和每一列含有字符的个数。
那么我们可以将s写成N字形后,将其看成numRows行,并创建类似[' ', ' ' , ......]的含有空格字符的列表来表示numRows行。
[' ', ' ' , ......], 设s的长度为n
=== >[ ' ', 第一行
' ', 第二行
...... ] 第n行
那么每一行的第一个字符肯定是s的前numRows个字符。
下面我们以例2为例分析
s = "PAYPALISHIRING", numRows = 4
P I N
A L S I G
Y A H R
P I[ ' P ', 第一行
' A ', 第二行
' Y ', 第三行
' P ', ] 第四行
接着第4+1个字符放在第4-1 = 3行
[ ' P ', 第一行
' A ', 第二行
' YA ', 第三行
' P ', ] 第四行
第4+2个字符放在第4 - 2 = 2行
[ ' P ', 第一行
' A L ', 第二行
' Y A ', 第三行
' P ', ] 第四行
第4+3个字符放在第4 - 3 = 1行
[ ' P I ', 第一行
' AL ', 第二行
' YA ', 第三行
' P ', ] 第四行
这时候需要进行转折
第4 + 4个字符放在第4 - 2 = 2行
[ ' P I ', 第一行
' ALS ', 第二行
' YA ', 第三行
' P ', ] 第四行
最后我们将第一行字符+第二行字符+第三行字符+第四行字符 = 新字符
我们得到规律:
那么每一行的第一个字符肯定是s的前numRows个字符。
接着第numRows+1个字符放在第n-1行
第numRows+2个字符放在第n - 2行
......
当将放到第一行和最后一行时进行转折。
最后将每一行的字符按顺序组合起来就形成了新字符
🌈代码实现
def convert(s, numRows): if numRows < 2: return s res = ["" for _ in range(numRows)] i, flag = 0, -1 for c in s: res[i] += c if i == 0 or i == numRows - 1: flag = -flag i += flag return "".join(res)
✏代码注释
def convert(s, numRows): if numRows < 2: return s # 创建用于储存行的列表 res = ["" for _ in range(numRows)] i, flag = 0, -1 # 初始化i的值和标记值,i表示第几行 for char in s: res[i] += char # 将字符加入到对应行 if i == 0 or i == numRows - 1: # 判断是否转折 flag = -flag # 根据标记值判断转折 i += flag # 这里的转折是通过对i +1,或-1实现的 return "".join(res) # 将列表变成字符串,也就是将所有行按顺序合并
遍历一次字符串s,时间复杂度为O(n),使用res储存新字符长度,空间复杂度为O(n).
今天就到这,明天见。🚀
❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄