6. N 字形变换

难度:中等

  • 题目
  • 示例
  • 思路
    • 1. 二维数组
    • 2. 列表字符串
    • 3. 使用flag

题目

将一个给定字符串 s s s 根据给定的行数 n u m R o w s numRows numRows ,以从上往下、从左到右进行 Z Z Z 字形排列。比如输入字符串为 “ P A Y P A L I S H I R I N G " “PAYPALISHIRING" PAYPALISHIRING" 行数为 3 3 3 时,排列如下:

6. N 字形变换_第1张图片
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如: “ P A H N A P L S I I G Y I R " “PAHNAPLSIIGYIR" PAHNAPLSIIGYIR"

示例

  1. 输入: s = “ P A Y P A L I S H I R I N G ” , n u m R o w s = 3 s = “PAYPALISHIRING”, numRows = 3 s=PAYPALISHIRING,numRows=3
    输出: “ P A H N A P L S I I G Y I R " “PAHNAPLSIIGYIR" PAHNAPLSIIGYIR"
  2. 输入: s = “ P A Y P A L I S H I R I N G " , n u m R o w s = 4 s = “PAYPALISHIRING", numRows = 4 s=PAYPALISHIRING",numRows=4
    输出: “ P I N A L S I G Y A H R P I " “PINALSIGYAHRPI" PINALSIGYAHRPI"
    解释:
    6. N 字形变换_第2张图片
  3. 输入: s = “ A " , n u m R o w s = 1 s = “A", numRows = 1 s=A",numRows=1
    输出: “ A " “A" A"

思路

1. 二维数组

简单来说就是先将原字符串从左到右排列成 Z Z Z 型存储到二维数组中,然后再按行顺序输出一个字符串即可。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ∗ n u m R o w s ) O(n*numRows) O(nnumRows)
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if len(s) < 3 or numRows == 1:
            return s
        # 定义一个 numRows 行、len(s)列的二维数组 matrix,用于存储按 Z 字形排列后的字符。
        matrix = [["" for _ in range(len(s))] for _ in range(numRows)]
        # 初始化变量 row 和 col,用于指示当前字符应该放在二维数组中的哪个位置。初始时,row=0,col=0
        row, col, down = 0, 0, True
        for i in range(len(s)):
            matrix[row][col] = s[i]
			# 如果 row=numRows-1,说明当前字符位于 Z 字形的最后一行,应该往上移动。
            if row == numRows-1:
                down = False
            # # 如果 row=0,说明当前字符位于 Z 字形的第一行,应该往下移动。
            elif row == 0:
                down = True
                
			# 此时 matrix[row][col] = s[i],并将 row 值加 1。
            if down:
                row += 1
            # 此时 matrix[row][col] = s[i],并将 row 值减 1,col 值加 1。
            else:
                row -= 1
                col += 1

        res = ""
        # 将二维数组按行连接成一个字符串 res,返回 res。
        for i in range(numRows):
            res += "".join(matrix[i])
        return res

2. 列表字符串

其实这种思路和二维数组差不多,只不过二维数据是先将字符按 Z Z Z 字型依次存入到数组中,再按照行的顺序依次读出来。但是第二种方法的思路为直接将字符存入到新的列表中,该列表由 n u m R o w s numRows numRows 个字符串组成,每一个字符串为一行的数据,直接将列表的内容顺序读出来即可。具体思路看代码。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

中间核心代码可以看图:
1.原始字符串排列为 Z Z Z字型后的下标位置
6. N 字形变换_第3张图片
2.用 a a a来判断属于竖列还是斜列
6. N 字形变换_第4张图片
3.用 b b b来表示该存入列表的哪个位置
6. N 字形变换_第5张图片

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if len(s) < 3 or numRows == 1:
            return s
        # 新建一个长度为numRows的字符串列表
        temp = ["" for _ in range(numRows)]
        n = len(s)
        # 遍历
        for i in range(n):
        # 用 a 判断该字符属于哪竖列还是斜列
            a = i // (numRows-1)
            # 用 b 来表示应该存储到的新列表的位置
            b = i % (numRows-1)
            # a为偶数为竖列
            if a % 2 == 0:
            # 直接将该字符正序存入到对应的列表位置
                temp[b] += s[i]
            # a为奇数为斜列,将它倒序存入到列表中
            else:
                temp[numRows-1-b] += s[i]
        # 直接输出
        res = ""
        for i in range(len(temp)):
            res += temp[i]
        return res

3. 使用flag

第三种方法也类似于第二种方法,建立一个由 n u m R o w s numRows numRows 个字符串组成的数组,将字符依次分别顺序存储到 n u m R o w s numRows numRows 个字符串中,每一个字符串为一行的数据。当在第一行和最后一行时为转折处,实行逆向存储,改变flag的值。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if len(s) < 3 or numRows == 1:
            return s
        # 新建数组
        temp = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for j in s:
            temp[i] += j
            # 转折处
            if i == 0 or i == numRows-1:
                flag = -flag
            i += flag
        
        return "".join(temp)

你可能感兴趣的:(LeetCode题解,算法,leetcode,职场和发展)