Leetcode 6 ZigZag Conversion

在这里插入图片描述
刚看到这个题目我是有点懵逼的,看懂题目都花了我好一会功夫。
先来说一下我自己的思路:我看到这个图我就觉得是有规律可循的,是不是能找出每一行元素的下标的通项,然后用个for loop给他们都整出来就好了。在我尝试后,我发现确实是有规律的,第一行和最后一行确实是有通项,但是中间的行没有唯一通项,他们有两个。然后我就陷入了纠结不知道这样做是否可行。再我看完标答的思路之后我发现是和我一样的,也是找规律的,官方给出的规律如下:

在这里插入图片描述
下面给出按照这种思路的写的解答:

    public String convert(String s, int numRows) {
        //方法一 row by row
        if(numRows == 1){ //一行的情况
            return s;
        }else{ //大于一行的情况
            StringBuilder str = new StringBuilder();
            int n = s.length();
            int cycleLen = 2 * numRows - 2; //这个cycleLen很重要,是找规律找出来的,可以自己画图找出这个周期
            for(int i = 0; i < numRows; i++){ //此for loop用来控制多少行,可以看到行数就是numRows。如果numRows=5,那么这个for loop就循环5次。具体操作就是依次将每一行的元素append进str中
                for(int j = 0; i + j < n; j+= cycleLen){ //此for loop就是将每一行该有的元素都找出来,加入到str中。
                    str.append(s.charAt(i + j)); //先append竖列上的
                    if(i != 0 && i!= numRows - 1 && j +  cycleLen - i < n){
                        str.append(s.charAt(j + cycleLen - i)); //再append斜列上的
                    }
                }
            }
            return str.toString();
        }
    }
   

上面这种方法其实是row by row的,依次将每行的元素加入到一个stringbuilder中。先把第一行的都加进去,再把第二行的都加进去。。。直到最后一行。

下面介绍第二种方法,这是discussion中highest votes的答案,我个人觉得非常的好,简单易懂。重要步骤的解释我都写上了注释,可能看起来会有些乱

    public String convert(String s, int numRows) {
        //方法二 character by character
        if(numRows == 1){return s;}
        
        char[] c = s.toCharArray(); //char类型数组,注意这边定义char[], c要小写,有点奇怪,我一直以为要大写
        int length = c.length; //注意c.length没有()
        StringBuilder[] sb = new StringBuilder[numRows]; //定义一个大小为numRows的stringbuilder类型的数组
        for(int i = 0; i< sb.length; i++){
            sb[i] = new StringBuilder(); //定义数组中每一个stringbuilder,这样每一个sb就可以单独拿出来使用了。假设numRows=5.那这边就一共5个sb,正好对应5行,每个sb存储相对应行数里的元素
        }
        
        //really elegant way! 建议跟着这个循环自己画图走一遍,这个算法就很容易明白了。光看的话很难懂
        int i = 0;
        while(i < length){
            for(int idx = 0; idx < numRows && i < length; idx++){
                sb[idx].append(c[i++]); //先垂直方向依次append元素
            }
            for(int idx = numRows - 2; idx >= 1 && i < length; idx--){
                sb[idx].append(c[i++]); //再斜右向上方向依次添加元素。整个过程就是先向下,再斜右向上,再竖直向下,再斜右向上。。。。以此类推
            }
        }
        
        for(int n =1; n < sb.length; n++){
            sb[0].append(sb[n]);
        }        
        return sb[0].toString();      
    }

总结

  1. 这题最主要的还是要找到规律,说是string题,其实我觉得更像math题
  2. 熟悉数组的使用
  3. 熟悉stringbuilder的使用
  4. tochararray(),将一个string转换为一个有次序的character squence
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值