面试经典150题——Z 字形变换

不要等待机会,而是创造机会

面试经典150题——Z 字形变换_第1张图片

题目描述:

面试经典150题——Z 字形变换_第2张图片

面试经典150题——Z 字形变换_第3张图片

面试经典150题——Z 字形变换_第4张图片


思路分析:

  • 首先观察输入输出:输入给定字符串 s 根据给定的行数 numRows,输出按照Z字形输出的字符串

面试经典150题——Z 字形变换_第5张图片

                      计算机解决问题,是用数字解决的

  • 那就不妨把输入输出字符串转化为数字来看一看,如果把字符转化成数字下标,会得到如下结果:

面试经典150题——Z 字形变换_第6张图片

  • 输出为:0-4-8-12-1-3-5-7-9-11-2-6-10

                      一次尝试找不到规律,那就再来一次

  • 当采用如下测试样例:

面试经典150题——Z 字形变换_第7张图片

  • 其对应的下标图表为:

面试经典150题——Z 字形变换_第8张图片

  • 输出为:0-6-12-1-5-6-11-13-2-4-8-10-3-9

现在看一下第一行输出的数字下标有规律吗?

第一次我的行数是3

首行:第一个下标0和第二个下标4相差4,第二个下标4和第三个下标8相差4

第二行:第一个下标1和第二个下标3相差2,但是第二个下标3和第三个下标5相差2,2+2仍然等于4;

末行:第一个下标2和第二个下标6相差4,第二个下标6和第三个下标10相差4

4 = 2 * (numRows=3 - 1)

第二次我的行数是4

首行:第一个下标0和第二个下标6相差6,第二个下标6和第三个下标12相差6

第二行:第一个下标1和第二个下标5相差4,但是第二个下标5和第三个下标7相差2,4+2仍然等于6;

第三行:第一个下标2和第二个下标5相差2,但是第二个下标4和第三个下标8相差4,2+4仍然等于6;

末行:第一个下标2和第二个下标6相差4,第二个下标6和第三个下标10相差4

6 = 2 * (numRows=4 - 1)

通过上面的大致总结,我们可以发现首行和末行是比较特殊的,需要单独处理,因为在第一个下标位置和第二个位置下标之间会夹着一个字母:

面试经典150题——Z 字形变换_第9张图片

同时,我们可以发现这个夹杂的字母下标是有规律的,再看看是什么规律(把每一行行标不要忘了)?

面试经典150题——Z 字形变换_第10张图片

可以看出:

5 = 算出的7 - 当前行数 * 24 = 算出的8 - 当前行数 * 2

 所以现在就可以有一个大体的解题方案了:

  • 首先按行遍历

  • 每行将所有包含的字符加入结果(注意是否超过字符串长度)

  • 当遍历到非首末行,需要计入这个夹杂的字母


代码实现:

public static String convert(String s, int numRows) {
    if (numRows == 1) {
        return s;
    }
    StringBuilder res = new StringBuilder();
    int n = s.length();
    // 按行遍历,逐行读取字符
    for (int i = 0; i < numRows; i++) {
        int j = i;
        while (j < n) {
            res.append(s.charAt(j));
            // 第一行和最后一行较为特殊,在中间会夹着一个字符,
            // 需要单独处理
            // 其下标为算出的 j 减去两倍的当前行数
            j += 2 * numRows - 2;
            if (i != 0 && i != numRows - 1 && j - 2 * i < n) {
                res.append(s.charAt(j - 2 * i));
            }
        }
    }
    return res.toString();
}

执行结果:

面试经典150题——Z 字形变换_第11张图片

顺便推广一下个人公众号:

面试经典150题——Z 字形变换_第12张图片面试经典150题——Z 字形变换_第13张图片

你可能感兴趣的:(算法)