跳到主要内容

6-Z字形变换

题目

6. Z 字形变换 - 力扣(LeetCode)

难度中等

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y I R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

/*
* @lc app=leetcode.cn id=6 lang=golang
*
* [6] Z 字形变换
*/

// @lc code=start
func convert(s string, numRows int) string {
matrix := make([][]byte, numRows)
for i := 0; i < numRows; i++ {
matrix[i] = make([]byte, 0)
}

for i, v := range []byte(s) {
if numRows == 1 {
matrix[0] = append(matrix[0], v)
continue
}
if i%(2*numRows-2) < numRows {
matrix[i%(2*numRows-2)] = append(matrix[i%(2*numRows-2)], v)
} else {
matrix[2*numRows-2-i%(2*numRows-2)] = append(matrix[2*numRows-2-i%(2*numRows-2)], v)
}
}

res := make([]byte, 0)
for _, v := range matrix {
res = append(res, v...)
}

return string(res)
}

// @lc code=end

这个特定的代码块:

if i%(2*numRows-2) < numRows {
matrix[i%(2*numRows-2)] = append(matrix[i%(2*numRows-2)], v)
} else {
matrix[2*numRows-2-i%(2*numRows-2)] = append(matrix[2*numRows-2-i%(2*numRows-2)], v)
}

首先,对于字符串中的每个字符,计算 i%(2numRows-2)。这里的 i 是字符在原始字符串中的索引,而 2numRows-2 是之字形的一个完整周期的长度(一个向下的垂直列和一个向上的斜列)。此计算结果给出当前字符在之字形周期中的位置。

判断当前位置是否在之字形的垂直部分。如果 i%(2*numRows-2) < numRows,这意味着字符位于垂直列中,因此应该按顺序放置在相应的行中。

如果不在垂直列中,即 i%(2numRows-2) >= numRows,这意味着字符位于斜向上的列中。在这种情况下,字符应该放在之字形中相应的行上,行数由 2numRows-2-i%(2*numRows-2) 计算得出。这个计算确保字符被放置在正确的行上,因为它从之字形的底部开始向上移动。

计算位置的解释

  • i%(2*numRows-2): 这个计算给出了在一个完整之字形周期内字符的位置。如果这个值小于 numRows,它就在垂直列中;否则,它就在斜向上的列中。
  • 2numRows-2-i%(2numRows-2): 当字符在斜向上的列中时,这个计算确定字符应该放在哪一行。这是因为在斜向上移动时,行号是递减的。