Z自行转换

问题

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:(下面这样的形状)
P A H N
A P L S I I G
Y I R
之后按逐行顺序依次排列:"PAHNAPLSIIGYIR"
实现一个将字符串进行指定行数的转换的函数:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) 应当返回 "PAHNAPLSIIGYIR" 。

思路

这个问题其实很简单,它只涉及到下标,你只要观察就能看出一个时间复杂度为O(n)的算法的。它是一个个重复的波形,而整个波形都是重复了从0开始到2×row-3这一段的波形,所以现在我暂时先只研究[0,2×row-3]这一段,[0,row-1]是竖直的,[row,2×row-3]是左下右上斜的。其中,第0行的下一个波形的下标与本波形同一行的相邻的下标相减是2×row-2-0=2×row-2。第1行本身波形与本身波形相邻的下标相减是2×row-3-1=2×row-4,下一个波形与本波形的相邻的下标相减是2,这两个差之和是2×row-2。再下一行就是2×row-6和4之和,也是2×row-2。所以问题的解法就出现了,从0到row-1进行遍历,现在正在遍历第i行,它先走了2×row-i×2的步长得到了一个字符,再走一个i×2就到了同一行下一个字符,如此往复地走直到越界为止,这一行就没了。虽然说循环有2层但是实际上却只进行了n步,所以时间复杂度是O(n)。但是对于行数只有1和行数大于等于字符串字符个数的情况,输出的字符串都是原来的字符串,不需要处理,直接输出就好。于是就得到了算法的实现。

使用

package com.company;

public class Main {

    public static void main(String[] args) {
    // write your code here
        String inputString = "PAYPALISHIRING";
        String inputString0 = "ABCDE";
        System.out.println(Solution.zigzagString0(inputString,4));
    }
}

输出

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


Process finished with exit code 0

实现

package com.company;

public class Solution {
    static public String zigzagString(String sourceString,int rows) {
        if (rows < 1 || sourceString == null) {
            System.out.println("输入非法");
            return "";
        }
        StringBuilder resultBuilder = new StringBuilder();
        for (int counter = 0;counter < rows;counter++) {
            if (rows == 1 || rows >= sourceString.length()) {
                return sourceString;
            } else {
                int stepLength = 2 * rows - 2 - 2 * counter;
                int counter0 = counter;
                while (counter0 < sourceString.length()) {
                    resultBuilder.append(sourceString.charAt(counter0));
                    if (stepLength != 2 * rows - 2 && stepLength != 0) {
                        counter0 += stepLength;
                        stepLength = 2 * rows - 2 - stepLength;
                    }
                    else if (stepLength == 0) {
                        stepLength = 2 * rows - 2;
                        counter0 += stepLength;
                    } else {
                        counter0 += stepLength;
                    }
                }
            }
        }
        return resultBuilder.toString();
    }

    /**
     * 这么做没什么不同,只不过是把字符串打印成Z字形。
     * @param sourceString
     * @param rows
     * @return
     */
    static public String zigzagString0(String sourceString,int rows) {
        if (rows < 1 || sourceString == null) {
            System.out.println("输入非法");
            return "";
        }
        StringBuilder resultBuilder = new StringBuilder();
        for (int counter = 0;counter < rows;counter++) {
            if (rows == 1 || rows >= sourceString.length()) {
                return sourceString;
            } else {
                int stepLength = 2 * rows - 2 - 2 * counter;
                int counter0 = counter;
                for (int counter1 = counter;counter1 < sourceString.length();counter1++) {
                    if (counter1 == counter0) {
                        System.out.print(sourceString.charAt(counter1));
                        if (stepLength != 2 * rows - 2 && stepLength != 0) {
                            counter0 += stepLength;
                            stepLength = 2 * rows - 2 - stepLength;
                        }
                        else if (stepLength == 0) {
                            stepLength = 2 * rows - 2;
                            counter0 += stepLength;
                        } else {
                            counter0 += stepLength;
                        }
                    } else {
                        System.out.print(" ");
                    }
                }
                System.out.println();
            }
        }
        return resultBuilder.toString();
    }
}

你可能感兴趣的:(Z自行转换)