LeetCode 6. Z 字形变换

LeetCode 6. Z 字形变换

题目

链接: https://leetcode.cn/problems/zigzag-conversion/

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数: 
string convert(string s, int numRows); 
示例 1: 输入:s = "PAYPALISHIRING", numRows = 3 
		 输出:"PAHNAPLSIIGYIR"

示例 2: 输入:s = "PAYPALISHIRING", numRows = 4 
		输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:
输入:s = "A", numRows = 1
输出:"A"
 

提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、‘,’ 和 ‘.’ 组成
1 <= numRows <= 1000

思路

  • 首先想到的又容易理解的就是模拟这个Z字变换啦,(tmd明明时N变换)
  • 设 len 为字符串 s 的长度,len=numRows。对于 row=1(只有一行)或者 row≥len(只有一列)的情况,直接返回 s。
  • 其余情况,考虑创建一个二维矩阵,然后在矩阵上按 Z 字形填写字符串 s,最后逐行扫描矩阵中的非空字符,组成答案。
  • 我们要的结果是矩阵中的非空字符,显然浪费了很多时间和空间,反正最后结果都是按行遍历(如下两个答案的输出是一样的),所以每一行的空字符索性就不存,直接每行用一个字符串存储,最后再拼成一个字符串
P   A   H   N
A P L S I I G
Y   I   R

P A H N
A P L S I I G
Y I R
  • 下面就是模拟的问题(以numRows = 3为例),我们选择 (numRow * 2 - 2)个为一个周期是最方便的(如下),最后就是利用周期t和numRows控制什么时候向下什么时候向右上,显然,当i % t < numRows - 1向下,否则向右上,自己在纸上写几个就明白了
P   
A P 
Y   

代码

class Solution {
    public String convert(String s, int numRows) {

        int len = s.length(); 
        if (numRows == 1 || numRows >= len) {
            return s;
        }
        StringBuffer[] sb = new StringBuffer[numRows];
        for(int i = 0; i < numRows; i++){
            sb[i] = new StringBuffer();
        }
        int t = numRows * 2 - 2; //2 * numRows - 2 为一个周期

        int row = 0;
        for(int i = 0; i < len; i++){//开始模拟
            sb[row].append(s.charAt(i));
            if(i % t < numRows - 1){//利用周期和行的关系判断是向下还是右上
                row ++;
            }else{
                row --;
            }
        }

        StringBuffer res = new StringBuffer();
        for(StringBuffer ss : sb){
            res.append(ss);
        }
        return res.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值