LeetCode06:Z字形变换

问题描述:输入一个字符串和给定数字nums,将字符串用长为nums的Z字形型展开,输出转换后的字符序列。

例:“PAHPZAISH”, 3
P____P____S
A _H_Z__I__H
H____A
输出:PPSAHZIHHA

思路

  • Z字入桶

把构建的Z字形按行看,每行对应一个桶,只要以Z字形将字符串按序投入桶内即可。
时间复杂度:o(n)
空间复杂度:o(n)

  • 按行输出

容易知道第0行和第nums-1行的下标数为行数与2nums - 2的累和,对于中间行数来说,简单对一个N的基本情况进行分析,观察每行第二个元素,可以看出行数每下一次,每行第一二个元素间隔会递减2个,即(2nums-2)- 2i,再观察第三个元素,可以看到第二三个元素间每下一行间隔加2,即2i;由于后面情况与此相同,故中间行数元素间间隔为前两者的交替。由此设计算法按下标遍历。
0_____6
1___5_7
2_4___8
3_____9
时间复杂度:o(n)
空间复杂度:o(n)

//java
//Z字入桶
class Solution {
    public String convert(String s, int numRows) {
        if(numRows < 2) return s;//长度太小直接输出即可
        ArrayList<StringBuilder> rows = new ArrayList<StringBuilder>();//构建字符串列表(放桶区域)
        for(int i = 0; i < numRows; ++i)  rows.add(new StringBuilder());//加入numRows个桶
        int i = 0, flag = -1;//i表示第几个桶,flag为掉头参数
        for(char str: s.toCharArray()){
            rows.get(i).append(str);
            if(i == 0 || i == numRows - 1)  //该掉头了
                flag = -flag;
            i += flag;
        } 
        StringBuilder res = new StringBuilder();//创建一个字符串准备收集桶中元素
        for(StringBuilder row: rows)    res.append(row);
        return res.toString();
    }
}

//按行遍历
class Solution {
    public String convert(String s, int numRows) {
        if(numRows < 2) return s;
        int len = s.length();
        int step = 2 * numRows - 2;//一般间隔
        StringBuilder res = new StringBuilder();//最终字符串
        for(int i = 0; i < numRows; ++i){
            int add = 2 * i;//中间行数步长调整
            int j = i;
            while(j < len){//遍历下标小于字符串长度
                res.append(s.charAt(j));
                add= step - add;//通过add值调整间隔(奇数次为step-add,偶数次为add)
                j += (i == 0 || i == numRows - 1)?  step : add;//行数区分
            }
        }
        return res.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Leo木

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

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

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

打赏作者

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

抵扣说明:

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

余额充值