微信公众号:三木小小推
系列:刷题之Python
如果你觉得该系列对你有帮助,欢迎点”好看”
问题描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
解决方案
class Solution:
def convert(self, s: str, numRows: int) -> str:
len_str = len(s)
mid_num = numRows - 2
len_cycle = numRows + mid_num
col_cycle = numRows - 1
numCols = (len_str // len_cycle + 1) * col_cycle
array = [["!" for i in range(numCols)] for j in range(numRows)]
sum_index = numRows - 1
mid_index = []
for i in range(1, sum_index):
mid_index.append([i, sum_index-i])
remain_num = len_str % len_cycle
add_str = "!" * remain_num
s += add_str
len_newstr = len(s)
for i in range(len_newstr // len_cycle):
for j in range(numRows):
array[j][col_cycle * i] = s[j + len_cycle * i]
for k in range(mid_num):
array[mid_index[k][0]][mid_index[k][1]+i*col_cycle] = s[numRows+len_cycle * i+k]
new_s = ""
for i in array:
for j in i:
if j != "!":
new_s += j
return new_s
sol = Solution()
print(sol.convert("PAYPALISHIRING", 3))
题目分析
思路
通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。
算法
我们可以使用min(numRows,len(s))min(numRows,len(s))个列表来表示 Z 字形图案中的非空行。
从左到右迭代 s,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。
只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) return s;
vector<string> rows(min(numRows, int(s.size())));
int curRow = 0;
bool goingDown = false;
for (char c : s) {
rows[curRow] += c;
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
string ret;
for (string row : rows) ret += row;
return ret;
}
};
欢迎订阅
下面是三木小小推的二维码,欢迎订阅呦~~

文章转载自三木小小推,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




