[力扣]6.Z 字形变换中等

tech2022-09-23  72

描述:

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L C I R E T O E S I I G E D H N 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。 请你实现这个将字符串进行指定行数变换的函数: string convert(string s, int numRows);

示例:

示例 1: 输入: s = "LEETCODEISHIRING", numRows = 3 输出: "LCIRETOESIIGEDHN" 示例 2: 输入: s = "LEETCODEISHIRING", numRows = 4 输出: "LDREOEIIECIHNTSG" 解释: L D R E O E I I E C I H N T S G

较优的解决方案:

class Solution { public String convert(String s, int numRows) { if(numRows < 2) return s; List<StringBuilder> rows = new ArrayList<StringBuilder>(); for(int i = 0; i < numRows; i++) rows.add(new StringBuilder()); int i = 0, flag = -1; for(char c : s.toCharArray()) { rows.get(i).append(c); if(i == 0 || i == numRows -1) flag = - flag; i += flag; } StringBuilder res = new StringBuilder(); for(StringBuilder row : rows) res.append(row); return res.toString(); } }

思路解析:

今天又聪明了一点点....刚开始的思路是你要几行我就声明几个数组,然后根据规律放到数组里,然后从构建好的数组中读取数据进行整合,惊不惊喜,意不意外,就是这么一点脑子都不动....然后发现这个规律好像不大好找,因为是 “Z” 字形排列,在 Z 的最后一划有点麻烦,但是我们真的需要将整个字符串分成几行(几个数组吗),其实不然,我们只需要找到这个排列的规律即可,然后根据规律对字符串进行重组,所以就对字符串中的每个字符进行了编号,以确定他在哪一行,详情请看下面的示例。

2行 LEETCODEIDHIRING 1212121212121212 3行 1232123212321232 4行 1234321234321234 5行 1234543212345432

通过这个示例可以看到,一个Z字其实是一个增减增的过程,我们可以进一步转化,从整体去看的话,将增减增看做转折点,则可以看到在1和最大行数时进行转折,转换为index则为0和 numRows时进行转折,有了这个思路,就可以进行构造,使用numRows个StringBuilder分别存储每一行的字符串,使用flag来标记上升(1)和下降(-1)的转折点(这个用的太妙了,佩服佩服),使用 i来标记每一行,使用flag来对i进行修改,在转折点的时候对flag进行反转,最后将所有的StringBuilder进行合并即可。

我的方法是用了map来对整个String的字符进行了分类,key为行号,value为一个list来存储该行的字符,最后进行合并。

 

最新回复(0)