【leecode】 6.ZigZag Conversion(锯齿形变换)

  • The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

  • And then read line by line: “PAHNAPLSIIGYIR”

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = “PAYPALISHIRING”, numRows = 3
Output: “PAHNAPLSIIGYIR”

Example 2:

Input: s = “PAYPALISHIRING”, numRows = 4
Output: “PINALSIGYAHRPI”
Explanation:
P I N
A L S I G
Y A H R
P I

解法一:用二维数组存放矩阵字符,遍历字符串,按照要求选择位置存放字符。

//该算法考虑的太多了,超时
    public  static String convert(String s, int numRows) {
        if (numRows==1) return s;//一行的情况
        if (s.length()<=numRows) return s;//
        int[][] a = new int[numRows][((s.length()/(2*numRows-2)+1)*(numRows))];//定义二维数组用来存储字符,最后在输出字符
        int i=0; //i在这里控制字符串的索引。
        String str = "";
        for (int m=0;m<a[0].length;m++){
            for (int n=0;n<a.length;n++){
                if (numRows==2)//两行的情况
                    if (m%2==1&n!=1){
                        if (i==s.length()){ break;}
                        a[n][m] = s.charAt(i);
                        i=i+1;
                    }else {
                        if (i == s.length()) { break; }
                        a[n][m] = s.charAt(i);
                        i = i + 1;
                    }
                if (numRows>2&&m%(numRows-1)!=0&& n == (numRows-m%(numRows-1)-1)){//m%(numRows-1)是筛选出有空的列, n == (numRows-m%(numRows-1)-1)是筛选出
                        if (i==s.length()){ break;}
                        a[numRows-m%(numRows-1)-1][m] = s.charAt(i);
                        i=i+1;
                }else if (numRows>2&&m%(numRows-1)==0){
                    if (i==s.length()){ break;}
                    a[n][m] = s.charAt(i);
                    i=i+1;
                }
            }
        }
        for (int k = 0;k<a.length;k++){
            for (int p =0;p<a[0].length;p++){
                    str += (char) a[k][p];
            }
        }
        return str.replace("\u0000","");
    }

解法二:根据规则,判断出是【行数减一】的图形成倍扩展,且整除【行数减一】的全部都排列字符,其他的列排一个,且按照递减的顺序,所以可以设置一个标志位flag,用来操作递减,从0-numrows或者从numrows-0,不断的迭代。

  public static String convert2(String s,int numRows){
        if (numRows==1) return s;
        List<StringBuilder> rows = new ArrayList<>();
        //给rows构造几行,如果字符串长度小于给定的长度,按照字符串的长度来定义
        for (int i =0;i<Math.min(s.length(),numRows);i++){ rows.add(new StringBuilder()); }
        int row = 0;
        Boolean flag = false;
        for (char c : s.toCharArray()){
            rows.get(row).append(c);
            //判断依据是第一行和最后一行,其它有空白列是根据全满的一列
            if(row==0||row==numRows-1) flag = !flag;
            row += flag ? 1 : -1;
        }
        //赋值完成,开始遍历
        StringBuilder res =  new StringBuilder();
        for (StringBuilder l : rows){
            res.append(l);
        }
        return res.toString();
    }
点赞