每日一题——Z字形变换

菜鸡每日一题系列打卡6

每天一道算法题目 

小伙伴们一起留言打卡

坚持就是胜利,我们一起努力!

题目描述(引自LeetCode)

将一个给定字符串根据给定的行数,以从上往下、从左到右进行Z字形排列。比如输入字符串为"LEETCODEISHIRING"行数为3时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"


示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:


L     D     R
E   O E   I I
E C   I H   N
T     S     G

题目分析

根据题目描述,比较容易想到的办法主要有两种。第一种是模拟字符串的Z字形排列,并利用多个StringBuilder对象分别记录每一行的结果,最后将每一行的结果进行拼接即可得到结果。但这种方法需要创建并维护多个StringBuilder变量,当numRows较大时,创建对象的开销是值得考虑的。因此,本文使用的是第二种解决方法,寻找字符串Z字形排列之后的字符与下标的规律,并仅创建一个StringBuilder即可完成字符串的拼接。

代码实现

class Solution {


    public String convert(String s, int numRows) {


        // 特殊情况处理
        if (numRows < 1) {
            throw new IllegalArgumentException("no solution!");
        }
        if (s == null || s.length() == 0 || numRows == 1) {
            return s;
        }


        // 用于字符串拼接
        StringBuilder builder = new StringBuilder();


        // 行数转化为行号(默认从0开始)
        int row = numRows - 1;


        // 起始行(末尾行)元素之间的下标间隔
        int step = 2 * row;


        // 针对每一行遍历
        for (int i = 0; i < numRows; i++) {


            // 记录索引的变化
            int index = i;


            // 记录非起始行(末尾行)间隔的变化
            int interval = step - 2 * i;


            while (index < s.length()) {
                builder.append(s.charAt(index));
                index += (i == 0 || i == row) ? step : interval;
                interval = step - interval;
            }


        }


        // 转换为字符串输出
        return builder.toString();


    }


}

代码分析

对代码进行分析,遍历操作完成了对s中所有字符的一次访问,因此,时间复杂度为O(n);由于需要额外的空间存储变换之后的字符串,因此,空间复杂度为O(n)。

执行结果

关注公众号有理想的菜鸡,和菜鸡一起打卡吧!点个在看让更多小伙伴看到。

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值