力扣 6. Z 字形变换

题目来源:https://leetcode-cn.com/problems/zigzag-conversion/

大致题意:
给一个字符串和行数 r,把字符串按照从上到下、从左到右进行 Z 字形排列,然后对排列后的字符串按照从左至右、从上到下的顺序取出、

思路

直接模拟变换过程

按照题目要求,在 Z 变换过程中,会先向下填 r 个字符,再向右上填 r - 2 个字符,这个过程可以视为一个周期 t = r * 2 - 2,那么一共有 n / t (向上取整,最后一个周期可能不完整,但是不影响)个周期

求出周期后,就可以按照周期变化规则进行模拟,为了节省内存,可以直接使用 StringBuffer 表示每行对应的字符串

模拟
  1. 求出周期 t
  2. 遍历整个字符串,索引为 i。初始时设行标记 x = 0。那么当 i mod t < r - 1 时,需要继续向下填字符,行数 x + 1;否则要向右上填字符,行数 x - 1
  3. 每次将索引 i 处的字符放入行标记 x 对应的 StringBuffer 对象末尾,然后根据当前索引 i 判断下一次应该放的行数

代码:

public String convert(String s, int numRows) {
        int n = s.length();
        int r = numRows;
        // 若行数为 1 或者大于字符串长度,直接返回原字符串即可
        if (r == 1 || r >= n) {
            return s;
        }
        // 周期
        int t = r * 2 - 2;
        // 行对应的字符串对象
        StringBuffer[] sb = new StringBuffer[r];
        for (int i = 0; i < r; i++) {
            sb[i] = new StringBuffer();
        }
        // 遍历
        for (int i = 0, x = 0; i < n; i++) {
            // 将当前字符放入对应行
            sb[x].append(s.charAt(i));
            // 判断下次放字符的行数
            if (i % t < r - 1) {
                x++;
            } else {
                x--;
            }
        }
        StringBuffer ans = new StringBuffer();
        for (int i = 0; i < r; i++) {
            ans.append(sb[i]);
        }
        return ans.toString();
    }

你可能感兴趣的:(leetcode,算法)