Leetcode #06:N 字形变换

题目

 将一个给定字符串 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.length <= 1000

  • s 由英文字母(小写和大写)、',' 和 '.' 组成

  • 1 <= numRows <= 1000

思路

认真思考过这道题的同学肯定知道传入的字符串中每一个字符都隐性的对应一个数字下标,最大是 numRows,最小是 0,从 0 按顺序先从小到大递增到 numRows-1 后又从大到小递减到 0,如此反复到字符串结尾。
例如: 传入字符串为 "PAHNAPLSIIGYIR", numRows 为 4, numRows-1 = 3 则其对应的数字下标为:
          P A H N A P L S I  I G Y I R
          0 1  2  3 2 1 0 1 2 3 2 1 0 1

我们可以通过数字下标的判断来拼接字符串。全程思路在代码演示中给出。

/**
 * @author: LoungeXi
 **/
public class Solution {
    public String convert(String s, int numRows) {
        // 定义存放数字下标的 List 集合
        List<Integer> indexList = new ArrayList<>();
        // 定义结果集
        StringBuilder result = new StringBuilder();
        // 为每一行要存入的字符都创建一个 StringBuilder , StringBuilder 放在 List 集合中
        List<StringBuilder> rowsList = new ArrayList<>();
        for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
            rowsList.add(new StringBuilder());
        }
        // 得到传入字符串的长度,减少方法调用
        int length = s.length();
        // 定义哨兵查看目前添加的数字下标是否达到字符串结尾
        int now = 0;
        // 未达到字符串结尾继续循环
        while (now < length) {
            // 添加本轮数字下标的左半段
            for (int flag = 0; flag < numRows; flag++) {
                if (now < length) {
                    indexList.add(flag);
                    now++;
                } else {
                    break;
                }
            }
            // 添加本轮数字下标的右半段
            for (int flag = numRows - 2; flag > 0; flag--) {
                if (now < length) {
                    indexList.add(flag);
                    now++;
                } else {
                    break;
                }
            }
        }
        // 根据数字下标在对应的 StringBuilder 中加入字符
        for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
            for (int flag = 0; flag < indexList.size(); flag++) {
                // 若得到数字下标与 StringBuilder 的索引相同则加入字符
                if (indexList.get(flag) == rowIndex) {
                    rowsList.get(rowIndex).append(s.charAt(flag));
                }
            }
        }
        // 拼接返回
        for (StringBuilder row : rowsList) {
            result.append(row);
        }
        return result.toString();
    }
}

优化

因为以上代码过于冗杂,因此对代码进行了优化,提高了性能,增强了可读性,但是思路没有变化。全程思路在代码演示中给出。

/**
 * @author: LoungeXi
 **/
public class Solution {
    public String convert(String s, int numRows) {
        // 若传入字符串的长度只有 2 可以直接返回
        if (numRows < 2) {
            return s;
        }
        // 为每一行要存入的字符都创建一个 StringBuilder , StringBuilder 放在 List 集合中
        List<StringBuilder> rows = new ArrayList<>();
        for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {
            rows.add(new StringBuilder());
        }
        // 定义好每一行的 StringBuilder 的索引 rowIndex
        int rowIndex = 0;
        // 这里 flag 的定义是为了传入字符串能找到各自应该加入的 StringBuilder
        int flag = -1;
        //循环加入字符
        for (char c : s.toCharArray()) {
            // 根据对应的数字下标将字符添加到对应的 StringBuilder
            rows.get(rowIndex).append(c);
            // 若 rowIndex == 0 代表数字下标需要递增 flag = 1,若 rowIndex == numRows - 1 代表数字下标需要递减 flag = -1
            if (rowIndex == 0 || rowIndex == numRows - 1) {
                flag = -flag;
            }
            // 递增或递减语句
            rowIndex += flag;
        }
        //拼接返回
        StringBuilder result = new StringBuilder();
        for (StringBuilder row : rows) {
            result.append(row);
        }
        return result.toString();
    }
}

总结

自己的思路还是不够开阔...........

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值