随笔 - 4  文章 - 0  评论 - 0  阅读 - 20

2024.09.22 力扣刷题 Z字形变换

题目:

将一个给定字符串 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"

上面就是题目的内容,难度标注的是中等,拿到题目读了有一会儿,刚开始不是很懂,后面看了示例大概明白了一些。
我当时的第一反应是进行字符串抽点,Z形应该是有规律可以找的,我设置了row = 3,4,5分别进行了规律查找:
当row = 3时,输入“PAYPALISHIRING”,通过观察Z形,可以看到下标0的P到A时需要有3个字符间隔,下标为1的A到P有1个字符间隔,到Y到I的字符间隔和第1个P到A的字符间隔一致。

但是需要注意的是,当row = 4或5时,其字符间隔会发生变化且数值有两种可能。如下所示(row = 4):

A到L的字符间隔数和L到S的字符间隔数会发生变化,且只有两种情况。

按此推论,从row = 3,4,5的情况下的字符排布,得出各行到下一个字符的间隔数遵循下述规律:
nums=2*(row-1-index)-1;
nums是字符间隔数,row是输入的行数,index是要拼接的每行的下标(若row=6,那么index=[0,5])
当row=4:
index=0,nums=5
index=1,nums=3
index=2,nums=1
index=3,nums=5(同index=0的情况)
也就是说index=0的P到I,中间需要跨5个字符,index=1的A到L需要跨3个字符,但是L到S需要跨1个字符,所以当row为偶数时,需要前后对称构成一组进行遍历,当row为奇数时,中间的index只需要按自己的nums进行遍历。

我提交的代码如下:

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1)
            return s;
        int* index = new int[numRows]{};
        for (int i = 0; i < (numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1); ++i) {
            if (i == (numRows - 1 - i)) {
                index[i] = 2 * (numRows - 1 - i) - 1;
            }
            else {
                index[i]= 2 * (numRows - 1 - i) - 1;
                index[numRows -1-i]= i == 0 ? index[i] : 2 * (numRows - 1 - (numRows - 1 - i)) - 1;
            }
        }

        int now_index = 0;
        std::string output;
        for (int i = 0; i < numRows; ++i) {
            now_index = i;
            std::string temp;
            bool flag = true;
            int a = index[i] + 1;
            int b = index[numRows - 1 - i] + 1;
            while (now_index < s.length()) {
                temp += s[now_index];
                now_index += flag ? a : b;
                flag = !flag;
            }
            output += temp;
        }
        delete[] index;

        return output;
    }
};

结果如下:

posted on   夏天喝啤酒  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示