LeetCode 第6题 Z字型变换

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)

猜你喜欢

转载自www.cnblogs.com/meloyang/p/12299969.html