leetcode Z字形变换

206 阅读2分钟
/**
 * 给一个字符串 s 和行数 n,从上往下,从左往右,进行 Z 字形排列,比如
 * s = "PAYPALISHIRING"      n = 3
 * P   A   H   N
 * A P L S I I G
 * Y   I   R
 * ================================================
 * s = "PAYPALISHIRING"      n = 4
 * P     I     N
 * A   L S   I G
 * Y A   H R
 * P     I
 * ================================================
 * 其实是镜像的 N 字形,非要说成 Z 字形
 */
  • 思路:
  1. 有点类似往哪一行里放什么字符,而不是把字符放到哪一行里;

  2. 遍历的是字符串 s,但同时是在控制 n 的下标,先正再反...1 2 3 2 1...

  3. 也就是说 n += 1 也有可能是 n += -1;而到底是 += 1 还是 += -1 要看下标是否为 0 或 是否为 n 的最大值

  • 以 s="PAYPALISHIRING";n=5 为例
  1. 遍历 s 开始

  2. n[0] 填进去 s[0];n[1] 填进去 s[1];n[2] 填进去 s[2];n[3] 填进去 s[3];n[4] 填进去 s[4]

  3. 诶,这时候,下标:4 已经是最后一个了,那么,开始反着走!

  4. n[3] 填进去 s[5];n[2] 填进去 s[6];n[1] 填进去 s[7];n[0] 填进去 s[8]

  5. 诶,这时候,下标:0 已经是最后一个了,那么,开始正着走!

  6. n[1] 填进去 s[9]...(未完待续)

  •   public class Test {
      
          public static void main(String[] args) {
              Test test = new Test();
              System.out.println(test.convert("PAYPALISHIRING", 5));
          }
      
          /**
           * 他这个思路有点类似往哪一行里放什么字符,而不是把字符放到哪一行里;遍历的是字符串 s,但同时是在控制 n 的下标,先正再反...1 2 3 2 1...
           * 也就是说 n += 1 也有可能是 n += -1;而到底是 += 1 还是 += -1 要看下标是否为 0 或 n
           * s="PAYPALISHIRING";n=5
           * 遍历 s 开始:
           * n[0] 填进去 s[0];n[1] 填进去 s[1];n[2] 填进去 s[2];n[3] 填进去 s[3];n[4] 填进去 s[4]
           * 诶,这时候,下标:4 已经是最后一个了,那么,开始反着走!
           * n[3] 填进去 s[5];n[2] 填进去 s[6];n[1] 填进去 s[7];n[0] 填进去 s[8]
           * 诶,这时候,下标:0 已经是最后一个了,那么,开始正着走!
           * n[1] 填进去 s[9]...(未完待续)
           */
          public String convert(String s, int numRows) {
              if (numRows == 1) return s;
              List<StringBuilder> rows = new ArrayList<>();
              //如果 s="ab" 也就是长度为 2,n = 3,那最后我的 n 其实只会装两个字符,所以有这么一下 Math.min(numRows, s.length())
              for (int i = 0; i < Math.min(numRows, s.length()); i++) {
                  rows.add(new StringBuilder());
              }
              int curRow = 0;
              boolean goingDown = false;//控制正、反走
              for (char c : s.toCharArray()) {
                  rows.get(curRow).append(c);
                  if (curRow == 0 || curRow == numRows - 1) {
                      goingDown = !goingDown;
                      System.out.printf("开始 %s 走!\n", goingDown ? "正" : "反");
                  }
                  curRow += goingDown ? 1 : -1;
              }
              StringBuilder ret = new StringBuilder();
              for (StringBuilder row : rows) {
                  ret.append(row);
              }
              return ret.toString();
          }
      
      }