LeetCode 第6题 Z字型变换
题目描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行?Z 字形排列。
比如输入字符串为 "LEETCODEASHARANG"?行数为 3 时,排列如下:
L???C???A???R
E?T?O?E?S?A?A?G
E???D???H???N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCARETOESAAGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
整体思路
我们通过观察不难发现,character在行中的分布是有规律可循的:每一行里的character,它们都有一个共同点。以题目中给的例子来说,第一行“L, C, A, R",它们在原string中的index分别是”0, 4, 8, 12",而最后一行“E, D, H, N",它们在原string中的index分别是”2, 6, 10, 14"。大家可能已经发现这个规律了:同一行中的character的index符合一个等差数列,而我们能很轻易地得出这个等差数列的通项公式。对于第二行“E, T, O, E, S, A, A, G",它们在原string的index分别为”1, 3, 5, 7, 9, 11, 13",这项规律似乎也能适用,只是前后差有所变化。
但是当我们改变numRows就会发现,规律并不仅仅是等差数列这么简单。如果我们将numRow改为4后,那么第二行character的index分布将不再遵循等差数列的规律。读者可自行绘画尝试。这里直接给出numRow改为4后第二行character的index分布变为了"1, 4, 6, 9, 11, 14, 16..."读者可以看到这一串数仍然是符合一定的规律的。描述这种规律的方式有很多,这里我门就用一种最适合用计算机语言的方法去描述:这些数除以(numRow+1)的余数为"行数-1”或“numRow+2-行数”。将例子代入,1 mod 5 = 1, 4 mod 5 = 4, 6 mod 5 = 1, 9 mod 5 = 4......
我们只需应用这个规律,然后再遍历字符串的过程中把每个character加入到合适的行中,最后合并list,就能得到最后的答案
代码实现
class Solution:
def convert(self, s: str, numRows: int) -> str:
# If the numRows is 1, no need for convertion
if numRows == 1:
return s
# Divided the string into numrow parts
# Each element in the list represent a row
# Each row is initialzed as empty string
string_list = list()
for i in range(numRows):
string_list.append("")
# Divisor is determined by the numRows
divisor = 2 * (numRows - 1)
for i in range(0, len(s)):
# Add the character to the correct place in the list
index = i % divisor
if index > divisor / 2:
index = divisor - index
string_list[index] += s[i]
return ''.join(string_list)
原文地址:https://www.cnblogs.com/meloyang/p/12299969.html