Algorithm——ZigZag Conversion

一、问题

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:

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

之后从左往右,逐行读取字符: "PAHNAPLSIIGYIR"

实现一个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "PAYPALISHIRING", numRows = 3
输出: "PAHNAPLSIIGYIR"

示例 2:

输入: s = "PAYPALISHIRING", numRows = 4
输出: "PINALSIGYAHRPI"
解释:

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

二、解决

JAVA

class Solution {
    public String convert(String s, int numRows) {

        if (numRows == 1) return s;

        List<StringBuilder> rows = new ArrayList<>();
        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;
            curRow += goingDown ? 1 : -1;
        }

        StringBuilder ret = new StringBuilder();
        for (StringBuilder row : rows) ret.append(row);
        return ret.toString();
    }
}

 JAVASCRIPT

var convert = function(s, numRows) {
    var strArr = s.split('');
    var arr = new Array(numRows);
    for (var i = 0; i < numRows; i++) {
        arr[i] = [];
    }

    if (numRows == 1) {
        return s;
    }

    var zig = 0, zag = numRows - 2;
    while (strArr.length > 0) {
        if (zig < numRows) {
            arr[zig].push(strArr.shift());
            zig++;
            zag = numRows - 2;
        } else if (zag > 0) {
            arr[zag].push(strArr.shift());
            zag--;                 
        }
        if (zag == 0 && zig == numRows) {
            zig = 0;
        }             
    }            

    var result = '';
    for (var m = 0; m < numRows; m ++) {
        for (var n = 0; n < arr[m].length; n++) {
            result += arr[m][n];
        }                
    }
};

 网上看到还有一种更高效的方法,然而没看懂。。。留待研究

我们注意到每一行的数字的索引是有规律的!

第一行和最后一行中索引相差是8, 即(5-1)*2

第二行时: 1+6 = 7,  7 + 2 = 9;  9 + 6 = 15;  15 + 2 = 17. ...   即在 6和2交替进行,逐个确定下一个索引的位置。  注意到 6+2 = 8, 2 = 2*1(索引值)

第三行时:2+4 = 6;  6 + 4 = 10; 10+4 = 14 ...   都是4, 可以理解为 是 4 和4 交替。 注意到 4+4 = 8;   4 = 2*2(索引值)

第四行时: 3+2 = 5; 5+6=10... 在6 和2之间交替。注意到 6+2 = 8;   4 = 2*3(索引值)

这规律可进行推广到第一行和最后一行。

所以根据当前位置,可以得到下一个字符的位置信息。可直接获取。 

这算法的时间复杂度为O(n), 空间复杂度为 O(1)
原文地址:https://www.cnblogs.com/bbcfive/p/10854856.html