LeetCode6—ZigZag Conversion

本类型博客中的各算法的时间复杂度分析均为博主自己推算,本类型博客也是博主自己刷LeetCode的自己的一些总结,因此个中错误可能较多,非常欢迎各位大神在博客下方评论,请不吝赐教


一、问题

  • 输入:输入一个字符串和整数
  • 输出:输出该字符串转换成zigzag形式之后的

二、输入输出示例

示例一:
  • 输入: 字符串为"PAYPALISHIRING",行数为3
  • 输出:"PAHNAPLSIIGYIR"
  • 输入的ZigZag字符串如下图所示:

三、解法


输出是Zigzag字符串每行的字符按照从左到右,从上到下的顺序依次拼接所得,因此如何每行的字符是解题的关键。观察发现对于要展示成n行的字符串,可以将其前2n-1个字符当作一组,然后该组中不同位置索引对应的行数是一定的,这是一种比较笨重的做法,另一种方法类似于找规律,观察可以发现每行字符在原字符串中的索引是有规律的,可以利用该规律直接获得每行对应的字符串。

解法一:找规律获得每行的字符串

解题思路:通过观察可以发现第一行和最后一行每个字符可以作为一组,前后两个字符的索引之差为numRows*2-2。而中间的每行可以将两个字符看作一组,两组字符的索引之差为numRows*2-2,而组内前后两个字符之间的索引差为 numRows*2-2-2*(当前行数-1),利用如上规律,即可直接获得每行的所有字符。
package com.happy.leetcode.p6;


public class ZigZagConversionV1 {


    public static void main(String[] args) {
        String s = "A";
        String an = "PAHNAPLSIIGYIR";
        String re = new ZigZagConversionV1().convert(s, 3);
        System.out.println(re.equals(an));
        System.out.println(an);
        System.out.println(re);
    }


    /**
     * zigzag对话转换方式
     * @param s 字符串
     * @param numRows 行数
     * @return
     */
    public String convert(String s, int numRows) {
        if(s.length()<=numRows || numRows==1) {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        int d = numRows*2-2;
        // 第一行
        for(int i=0; i<s.length(); i+=d) {
            sb.append(s.charAt(i));
        }
        // 第二行到第numRows-1行
        for(int j=1; j<numRows-1; j++) {
            for(int i=j; i<s.length(); i+=d) {
                sb.append(s.charAt(i));
                if(i+d-j*2<s.length()) {
                    // 组内两个字符之间相差i+d-j*2
                    sb.append(s.charAt(i+d-j*2));
                }
            }
        }
        // 最后一行
        for(int i=numRows-1; i<s.length(); i+=d) {
            sb.append(s.charAt(i));
        }
        return sb.toString();
    }


}

时间复杂度分析:遍历numRows行,每行遍历的时间复杂度为O(n),因此总的时间复杂度为 O(numRows*n),其中n表示字符串长度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值