墨风如雪博客

  • 源码小店
  • 导航站
  • 登录
  • java
  • 资源分享
让AI使用变得如此简单
  1. 首页
  2. 算法
  3. 正文

每日算法题:Z字形变换算法实现

2023年 6月 10日 70点热度 0人点赞 0条评论

问题描述

给定一个字符串,将其按Z字形排列,并按行从左到右,再从右到左交替输出。例如,输入字符串为 "LEETCODEISHIRING",排列成下图所示的样子后输出 "LCIRETOESIIGEDHN"。

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

算法步骤

  1. 创建一个二维数组;
  2. 遍历字符串;
  3. 计算每个字符对应的坐标;
  4. 将字符填入对应的坐标;
  5. 从上到下,从左到右,从右到左遍历二维数组,将每个字符拼接起来。

实现思路

A. 创建一个二维数组

定义一个二维数组zigzag,行数为输入字符串的行数,列数为输入字符串的长度。

char[][] zigzag = new char[numRows][s.length()];

B. 遍历字符串

遍历输入字符串s的每个字符。

C. 计算每个字符对应的坐标

计算每个字符对应的行列坐标。当以Z字形排列时,每一行的字符排列存在一定的规律:

第0行排列:0   6    12
第1行排列:1 5 7  11 13
第2行排列:2 4 8 10  14
第3行排列:3   9    15

当下标i处于0~numRows-1时,表示处于Z字形的上升部分。对应的列坐标可以直接计算出来为i。当下标处于numRows~2*numRows-2时,表示处于Z字形的下降部分。对应的列坐标可以计算出来为(numRows-1)-(i-(numRows-1))。

int row = 0, col = 0;
for (int i = 0; i < s.length(); i++) {
    zigzag[row][col] = s.charAt(i);
    if (row == 0) {
        col++;
    } else if (row == numRows - 1) {
        col++;
        row--;
    } else {
        col++;
        row--;
    }
}

D. 将字符填入对应的坐标

将每个字符填入计算出来的对应坐标。

for (int i = 0; i < numRows; i++) {
    for (int j = 0; j < s.length(); j++) {
        if (zigzag[i][j] != 0) {
            result.append(zigzag[i][j]);
        }
    }
}

代码实现

完整的代码实现如下:

public String convert(String s, int numRows) {
    if (numRows == 1) {
        return s;
    }
    char[][] zigzag = new char[numRows][s.length()];
    int row = 0, col = 0;
    // 遍历字符串,计算每个字符所处的位置
    for (int i = 0; i < s.length(); i++) {
        zigzag[row][col] = s.charAt(i);
        if (row == 0) {
            col++;
        } else if (row == numRows - 1) {
            col++;
            row--;
        } else {
            col++;
            row--;
        }
    }
    StringBuilder result = new StringBuilder();
    // 从上到下,从左到右,从右到左遍历二维数组,将每个字符拼接起来
    for (int i = 0; i < numRows; i++) {
        for (int j = 0; j < s.length(); j++) {
            if (zigzag[i][j] != 0) {
                result.append(zigzag[i][j]);
            }
        }
    }
    return result.toString();
}

时间复杂度分析

时间复杂度为$O(n)$,其中$n$为输入字符串的长度。

空间复杂度分析

空间复杂度为$O(n)$,需要存储一个二维数组,数组大小为$numRows \times n$。

优化思路

遍历一次字符串,计算每个字符对应的位置,然后遍历一次数组,按顺序将每个位置上的字符加入结果中。对于长度为$n$的字符串,时间复杂度为$O(n)$。原理上无法得到更快的算法,但是可以通过一些优化方法降低时间复杂度。

扩展点

A. 处理非字母字符

如果输入字符串不仅仅包含字母,还包含其他字符(例如空格、数字等),那么需要对算法进行修改。可以将取值范围限定在字母范围内,当遍历到非字母字符时直接跳过。

B. Z字形变换的逆过程

Z字形变换的逆过程是将排列好的字符串重新排列成原来的字符串。这个过程可以按照原来的方法,计算每个字符在原来字符串中对应的位置,然后按照顺序添加到结果字符串中即可。

总结

本文介绍了Z字形变换算法的实现过程。该算法是一种基于规律的算法,通过计算每个字符对应的行列坐标,然后按照行列坐标填充二维数组。最后,按照约定的顺序从二维数组中取出字符,即可得到排列好的字符串。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: java 字符串 思路 教程 数字 数据结构 算法 算法详解 过程
最后更新:2025年 3月 24日

墨风如雪

一个热爱生活,热爱分享的程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

墨风如雪

一个热爱生活,热爱分享的程序员

最新 热点 随机
最新 热点 随机
告别机械感!OpenAudio S1让AI声音活起来 Sora触手可及!微软必应AI视频生成器,全民创作时代来临? 阿里WebAgent开源:引领自主搜索新纪元 重磅炸弹!字节跳动开源BAGEL:70亿参数,统一多模态理解与生成,AI“全能王”诞生记! 小米MiMo-VL:7B参数,怎么就成了多模态界的“越级打怪王”? 炸裂!DeepSeek 8B 量化版降临:告别显存焦虑,你的 3080 Ti 也能玩转顶级大模型了!
AI圈炸锅了!Mistral Medium 3:性能 SOTA,成本打骨折,企业玩家的新宠?字节终于开源“扣子”同款引擎了!FlowGram:AI 时代的可视化工作流利器告别“微信黑箱”!Chatlog:让你的聊天记录也能拥有“AI大脑”!字节跳动 Seed-Coder-8B:不靠人工洗数据,这80亿参数的小模型如何写出顶尖代码?85倍速的视觉革命:苹果发布 FastVLM,让你的 iPhone ‘看图说话’,快到飞起!告别AI视频“变脸怪”!腾讯混元Hunyuan Custom重磅开源,主体一致性“王炸”来了!
抽象类和接口的区别(通俗易理解) Java 当中的只要组成部分 JVM java Web框架Play的(超详细总结) Java线程池参数和调优 AI“神医”的开源盛宴?谷歌医疗大模型MedGemma来了! 不一样的视角 解析NoSQL数据库 Apache CouchDB
标签聚合
动态规划 教程 spring deepseek 算法 设计模式 java AI

COPYRIGHT © 2023 墨风如雪博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

免责声明 - 隐私政策