题意

image.png

解题思路:

  • 题目理解:
    1. 字符串 s 是以 ZZ 字形为顺序存储的字符串,目标是按行打印。
    2. 设 numRows 行字符串分别为 S1,S2,,,,,Sn,则容易发现:按顺序遍历字符串 S 时,每个字符 c 在 Z字形中对应的行索引先从 S1增大至Sn,再从Sn减小至S1,,,如此反复
    3. 因此,解决方案为:模拟这个行索引的变化,在遍历 s 中把每个字符填到正确的行 res[i]
  • 算法流程:按顺序遍历字符串 s;
    1. res[i] += c: 把每个字符 c 填入对应行 si;
    2. i += flag: 更新当前字符 c 对应的行索引;
    3. flag = - flag: 在达到 ZZ 字形转折点时,执行反向。
  • 复杂度分析:
    1. 时间复杂度 O(N) :遍历一遍字符串 s;
    2. 空间复杂度 O(N) :各行字符串共占用 O(N) 额外空间。

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param String $s
  4. * @param Integer $numRows
  5. * @return String
  6. */
  7. function convert($s, $numRows) {
  8. $res = array_fill(0, $numRows, '');
  9. $falg = -1;
  10. $j = 0;
  11. for ($i = 0; $i < strlen($s); $i++) {
  12. $res[$j] .= $s[$i];
  13. //开头=》增大,结尾=》减小
  14. if ($j == 0 || $j == $numRows - 1) {
  15. $falg = 0 - $falg;
  16. }
  17. $j += $falg;
  18. }
  19. return implode('', $res);
  20. }
  21. //1 使用二维数组存储对应字符的位置,最后输出整理结果字符串
  22. //2 采用标志位,标识存入方向的向上向下,注意边界条件
  23. function convert($s, $numRows) {
  24. $len = strlen($s);
  25. if ($len == 1 && $len == $numRows) return $s;
  26. $arr = [];
  27. $sign = 'down';
  28. $pre = -1;
  29. for ($i = 0; $i < $len; $i++) {
  30. if ($sign == 'down') {
  31. // 方向向下
  32. $arr[++$pre][] = $s[$i];
  33. // 到底部了,改方向为向上
  34. if ($pre == $numRows-1) $sign = 'up';
  35. } else {
  36. // 方向向上
  37. $arr[--$pre][] = $s[$i];
  38. // 到顶部了,改方向为向下
  39. if ($pre == 0) $sign = 'down';
  40. }
  41. }
  42. // 整理为字符串
  43. $resStr = '';
  44. foreach ($arr as $v) {
  45. foreach ($v as $vv) {
  46. $resStr .= $vv;
  47. }
  48. }
  49. return $resStr;
  50. }

GO代码实现:

  1. func convert(s string, numRows int) string {
  2. if len(s) <= 2 || numRows == 1{
  3. return s
  4. }
  5. res := make([]string, numRows)
  6. flag := -1
  7. j := 0
  8. for _, v := range s {
  9. res[j] += string(v)
  10. if j == 0 || j == numRows-1 {
  11. flag = -flag
  12. }
  13. j += flag
  14. }
  15. return strings.Join(res, "")
  16. }

参考资料:

Leetcode