6. Z 字形变换 :「模拟」&「数学」

简介: 6. Z 字形变换 :「模拟」&「数学」

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 6. Z 字形变换 ,难度为 中等


Tag : 「模拟」、「数学」


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


比如输入字符串为 "PAYPALISHIRING" 行数为 33 时,排列如下:


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 <= 10001<=s.length<=1000
  • s 由英文字母(小写和大写)、',''.' 组成
  • 1 <= numRows <= 10001<=numRows<=1000


模拟



由于最终是要我们对 Z 型矩阵进行从上往下、从左往右的构建输出。


因此可以构建一个矩阵 g 存储 Z 型中的每行字符(忽略 Z 中的空格间隙),同时使用 idxs 存储 Z 型中每行用到的下标。


目标 Z 型 和 矩阵 g 以及 idxs 三者关系:


P     I    N             PIN                3
A   L S  I G    =>       ALSIG     =>       5
Y A   H R                YAHR               4
P     I                  PI                 2   
复制代码


代码:


class Solution {
    static int N = 1010;
    static char[][] g = new char[N][N];
    static int[] idxs = new int[N];
    public String convert(String s, int m) {
        if (m == 1) return s;
        int n = s.length();
        Arrays.fill(idxs, 0);
        for (int i = 0, j = 0, k = 1; i < n; i++) {
            g[j][idxs[j]++] = s.charAt(i);
            j += k;
            if (j < 0) {
                j += 2; k = 1;
            } else if (j == m) {
                j -= 2; k = -1;
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < idxs[i]; j++) {
                sb.append(g[i][j]);
            }
        }
        return sb.toString();
    }
}
复制代码


  • 时间复杂度:创建数组的工作只会发生一次,清空 idxs 数组操作会发生在每个样例中,复杂度为 O(m)O(m);将 s 的每个字符填入矩阵的复杂度为 O(n)O(n);从矩阵中取出字符构建答案复杂度为 O(n)O(n)。整体复杂度为 O(m + n)O(m+n)
  • 空间复杂度:O(n * m)O(nm)


数学规律



对于本题,我们可以不失一般性的将规律推导为「首项」和「公差公式」。


这通常能够有效减少一些判断。


分情况讨论:


  • 对于第一行和最后一行:公差为 2 * (n − 1) 的等差数列,首项是 i
  • 对于其他行:两个公差为 2 * (n − 1) 的等差数列交替排列,首项分别是 i2 * n − i − 2


代码:


class Solution {
    public String convert(String s, int r) {
        int n = s.length();
        if (n == 1 || r == 1) return s;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < r; i++) {
            if (i == 0 || i == r - 1) {
                int pos = i, offset = 2 * (r - 1);
                while (pos < n) {
                    sb.append(s.charAt(pos));
                    pos += offset;
                }
            } else {
                int pos1 = i, pos2 = 2 * r - i - 2;
                int offset = 2 * (r - 1);
                while (pos1 < n || pos2 < n) {
                    if (pos1 < n) {
                        sb.append(s.charAt(pos1));
                        pos1 += offset;
                    }
                    if (pos2 < n) {
                        sb.append(s.charAt(pos2));
                        pos2 += offset;
                    }
                }
            }
        }
        return sb.toString();
    }
}
复制代码


  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.6 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
BackTrader 中文文档(二十一)(2)
BackTrader 中文文档(二十一)
127 0
|
Prometheus 监控 前端开发
Alertmanager 告警|学习笔记(四)
快速学习 Alertmanager 告警
561 0
Alertmanager 告警|学习笔记(四)
|
JavaScript UED
记一个“奇葩”需求的实现
记一个“奇葩”需求的实现
245 0
记一个“奇葩”需求的实现
|
JavaScript 前端开发 中间件
VUE 服务器端渲染-NUXT
VUE 服务器端渲染-NUXT
167 0
|
应用服务中间件 Go nginx
排查go开发的HttpClient读取Body超时
记一次go httpclient [读取响应Body超时]的排查过程。 今年度解锁的第一个技能
排查go开发的HttpClient读取Body超时
|
缓存 Java 测试技术
Shiro第三篇【授权过滤器、与ehcache整合、验证码、记住我】(一)
本文主要讲解的知识点有以下: Shiro授权过滤器使用 Shiro缓存 与Ehcache整合 Shiro应用->实现验证码功能 记住我功能
195 0
Shiro第三篇【授权过滤器、与ehcache整合、验证码、记住我】(一)
|
人工智能 C语言 C++
啪啪啪:动态数组
啪啪啪:动态数组
|
机器学习/深度学习 人工智能 自然语言处理
NLP:LSTM之父眼中的深度学习十年简史《The 2010s: Our Decade of Deep Learning / Outlook on the 2020s》的参考文献
NLP:LSTM之父眼中的深度学习十年简史《The 2010s: Our Decade of Deep Learning / Outlook on the 2020s》的参考文献