题意
解题思路:
- 题目理解:
- 字符串 s 是以 ZZ 字形为顺序存储的字符串,目标是按行打印。
- 设 numRows 行字符串分别为 S1,S2,,,,,Sn,则容易发现:按顺序遍历字符串 S 时,每个字符 c 在 Z字形中对应的行索引先从 S1增大至Sn,再从Sn减小至S1,,,如此反复
- 因此,解决方案为:模拟这个行索引的变化,在遍历 s 中把每个字符填到正确的行 res[i]
- 算法流程:按顺序遍历字符串 s;
- res[i] += c: 把每个字符 c 填入对应行 si;
- i += flag: 更新当前字符 c 对应的行索引;
- flag = - flag: 在达到 ZZ 字形转折点时,执行反向。
- 复杂度分析:
- 时间复杂度 O(N) :遍历一遍字符串 s;
- 空间复杂度 O(N) :各行字符串共占用 O(N) 额外空间。
PHP代码实现:
class Solution { /** * @param String $s * @param Integer $numRows * @return String */ function convert($s, $numRows) { $res = array_fill(0, $numRows, ''); $falg = -1; $j = 0; for ($i = 0; $i < strlen($s); $i++) { $res[$j] .= $s[$i]; //开头=》增大,结尾=》减小 if ($j == 0 || $j == $numRows - 1) { $falg = 0 - $falg; } $j += $falg; } return implode('', $res); } //1 使用二维数组存储对应字符的位置,最后输出整理结果字符串 //2 采用标志位,标识存入方向的向上向下,注意边界条件 function convert($s, $numRows) { $len = strlen($s); if ($len == 1 && $len == $numRows) return $s; $arr = []; $sign = 'down'; $pre = -1; for ($i = 0; $i < $len; $i++) { if ($sign == 'down') { // 方向向下 $arr[++$pre][] = $s[$i]; // 到底部了,改方向为向上 if ($pre == $numRows-1) $sign = 'up'; } else { // 方向向上 $arr[--$pre][] = $s[$i]; // 到顶部了,改方向为向下 if ($pre == 0) $sign = 'down'; } } // 整理为字符串 $resStr = ''; foreach ($arr as $v) { foreach ($v as $vv) { $resStr .= $vv; } } return $resStr;}
GO代码实现:
func convert(s string, numRows int) string { if len(s) <= 2 || numRows == 1{ return s } res := make([]string, numRows) flag := -1 j := 0 for _, v := range s { res[j] += string(v) if j == 0 || j == numRows-1 { flag = -flag } j += flag } return strings.Join(res, "")}
参考资料: