力扣LeetCode算法题 第6题-Z 字形变换

要求:

一开始看到题目,第一想到的思路,就被题目要求的思路给带偏了。

内容是Z字型输出内容

 就一直想着把字符串输出成上面这种格式

总是想着把字符串放入到二维数组中进行展示。

这样一来思路就受到了限制。

一直使用先写入数组中。

//将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
    //比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
    public static String convert1(String s, int numRows) {
        System.out.println("s.length="+s.length());
        //想法和思路。Z字格设计,其实就是把数字一个个放进到二维数组中。再按照顺序去读取出来。
        //二维 数组的长度length=s.length/(width-1),width=numRows
        int arr_width = numRows;
        int arr_length = s.length()/(arr_width-1);
        int lie_mark=0;//向右进位标记
        int hang_mark=0;//向下进位标记

        //根据长度进行生成数组
        int[][] arrays = new int[arr_width][arr_length];
        //因为Z字写入数据,需要反向写入数据,涉及到了标记。
        int flag =-1;//flag==1,则从上往下写。  flag==-1,从下往上写。
        // i=0 ,1,2    i=3反向  i=5反向  i =9
        int flag_count =0;
        //记录结果
        int result=0;
        if(numRows==1){
            return s;
        }else {
            for (int i = 0; i < s.length(); i++) {
                hang_mark=flag_count;
//                System.out.println("i="+i);
//                System.out.println("lie_mark="+lie_mark);
//                System.out.println("hang_mark="+hang_mark);
                arrays[hang_mark][lie_mark]=s.charAt(i);
                if(flag_count==0  && flag_count==numRows-1){
                    flag=-flag;//反向
                }
                //判断什么时候往下写
                if(flag==1){//向下输出
                    flag_count++;
                }
                //判断什么时候向上斜写,(x+1)(y-1)
                if(flag==-1){//向上输出
                    flag_count--;
                    lie_mark++;
                }
                System.out.println("flag_count="+flag_count);
            }
        }

        //测试遍历二维数组
        for (int i = 0; i < arr_length; i++) {
            for (int j = 0; j < arr_width; j++) {
                System.out.print(" " +String.valueOf(arrays[i][j]));
            }
            System.out.println('\n');
        }


        return "";
    }

该功能还没写完,还存在测BUG.有待完善。

而在后续中,又想到一种办法,那就是不去一个个的写入。直接由果推导因。

我们的最终结果是字符串形式,那么我们就直接用字符串去进行拼接就行。

public static String convert(String s, int numRows) {
        //用于接收字符串组
        StringBuilder[] results = new StringBuilder[numRows];
        //String对象赋值
        for (int i = 0; i < numRows; i++) {
            results[i]=new StringBuilder();
        }
        //反向输出标志:
        int flag_count=0;//反向计数器。=0或者=numRows-1的时候说明到顶和底了,可以反向
        int flag = -1;// =1向下输出,=-1向上输出
        //判空
        if(numRows==1) return s;

        for(int i=0;i<s.length();i++){
            //按照结果意愿来进行存放
            results[flag_count].append(s.charAt(i));

            //判断顶底,进行反向输出
            if(flag_count==0 || flag_count==(numRows-1))
                flag=-flag;

            //计数器工作,每次循环计数一次
            if(flag==1)
                flag_count++;//=0向下输出
            else
                flag_count--;//=1向上输出
        }

        StringBuilder display = new StringBuilder();
        for (int i = 0; i < numRows; i++) {
            display.append(results[i].toString());
        }

        return display.toString();
    }

下面是调试的字符串结果:

算法解释:

1.根据flag来进行判断向上输出还是向下输出

2.根据flag_count来判断顶底,到了顶底进行反向。

附上所有的代码:

package com.zhm.test;

/**
 * @Author bige
 * @Date: 2022/11/28 10:37
 * @ApiNote:Z 字形变换
 */
public class Leetcode_test006 {
    //将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
    //比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
    public static String convert1(String s, int numRows) {
        System.out.println("s.length="+s.length());
        //想法和思路。Z字格设计,其实就是把数字一个个放进到二维数组中。再按照顺序去读取出来。
        //二维 数组的长度length=s.length/(width-1),width=numRows
        int arr_width = numRows;
        int arr_length = s.length()/(arr_width-1);
        int lie_mark=0;//向右进位标记
        int hang_mark=0;//向下进位标记

        //根据长度进行生成数组
        int[][] arrays = new int[arr_width][arr_length];
        //因为Z字写入数据,需要反向写入数据,涉及到了标记。
        int flag =-1;//flag==1,则从上往下写。  flag==-1,从下往上写。
        // i=0 ,1,2    i=3反向  i=5反向  i =9
        int flag_count =0;
        //记录结果
        int result=0;
        if(numRows==1){
            return s;
        }else {
            for (int i = 0; i < s.length(); i++) {
                hang_mark=flag_count;
//                System.out.println("i="+i);
//                System.out.println("lie_mark="+lie_mark);
//                System.out.println("hang_mark="+hang_mark);
                arrays[hang_mark][lie_mark]=s.charAt(i);
                if(flag_count==0  && flag_count==numRows-1){
                    flag=-flag;//反向
                }
                //判断什么时候往下写
                if(flag==1){//向下输出
                    flag_count++;
                }
                //判断什么时候向上斜写,(x+1)(y-1)
                if(flag==-1){//向上输出
                    flag_count--;
                    lie_mark++;
                }
                System.out.println("flag_count="+flag_count);
            }
        }

        //测试遍历二维数组
        for (int i = 0; i < arr_length; i++) {
            for (int j = 0; j < arr_width; j++) {
                System.out.print(" " +String.valueOf(arrays[i][j]));
            }
            System.out.println('\n');
        }


        return "";
    }

//    例如对一个4行的
//
//        0     6      12        18
//        1   5 7   11 13    17
//        2 4   8 10   14 16
//        3     9      15
//
//    对于n行的, s中的第i个字符:lie=i%(numrows-1).
//    对余数进行判断
//    i%(2n-2) == 0 ----> row0
//    i%(2n-2) == 1 & 2n-2-1 ----> row1
//    i%(2n-2) == 2 & 2n-2-2 ----> row2
//    i%(2n-2) == 3
//    ...
//    i%(2n-2) == n-1 ----> row(n-1)
//    ==>
//    对 k = i%(2n-2)进行判断
//    k<=n-1时候,s[i]就属于第k行
//    k>n-1时候,s[i]就属于2n-2-k行
//            最后将rows拼接起来就行了
    public static String convert(String s, int numRows) {
        //用于接收字符串组
        StringBuilder[] results = new StringBuilder[numRows];
        //String对象赋值
        for (int i = 0; i < numRows; i++) {
            results[i]=new StringBuilder();
        }
        //反向输出标志:
        int flag_count=0;//反向计数器。=0或者=numRows-1的时候说明到顶和底了,可以反向
        int flag = -1;// =1向下输出,=-1向上输出
        //判空
        if(numRows==1) return s;

        for(int i=0;i<s.length();i++){
            //按照结果意愿来进行存放
            results[flag_count].append(s.charAt(i));

            //判断顶底,进行反向输出
            if(flag_count==0 || flag_count==(numRows-1))
                flag=-flag;

            //计数器工作,每次循环计数一次
            if(flag==1)
                flag_count++;//=0向下输出
            else
                flag_count--;//=1向上输出
        }

        StringBuilder display = new StringBuilder();
        for (int i = 0; i < numRows; i++) {
            display.append(results[i].toString());
        }

        return display.toString();
    }
//        0     6      12        18
//        1   5 7   11 13    17
//        2 4   8 10   14 16
//        3     9      15
    public static void main(String[] args) {
        //String s = "0123456789876543210";
        String s = "PAYPALISHIRING";
        //convert(s,3);
        System.out.println("result = " + convert1(s,3));
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逼哥很疯狂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值