欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 力扣面试经典算法150题:Z 字形变换

力扣面试经典算法150题:Z 字形变换

2024/10/25 10:34:25 来源:https://blog.csdn.net/weixin_48668564/article/details/141826916  浏览:    关键词:力扣面试经典算法150题:Z 字形变换

Z 字形变换

今天的题目是力扣面试经典150题中的数组的中等难度题: Z 字形变换。

题目链接:https://leetcode.cn/problems/zigzag-conversion/description/?envType=study-plan-v2&envId=top-interview-150

题目描述

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

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P	  A	    H	  N 
A  P  L  S  I  I  G 
Y	  I	    R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

  • 示例 1:

    • 输入:
      s = “PAYPALISHIRING”, numRows = 3

    • 输出:
      “PAHNAPLSIIGYIR”

    • 解释:

      P	  A	    H	  N 
      A  P  L  S  I  I  G 
      Y	  I	    R
      
  • 示例 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”

    • 解释:
      没法转换,直接返回字符串

题目分析

题目会给定一个字符串和一个数字num,要求把字符串分成num行。在分行的时候,要求按列Z字形排列。

其实这个Z字形可能不是很直观,再拆分成一个类似字的左边的竖提就清晰一点。

用示例来讲解一下:

  1. 示例一:
    P-A-Y-P组成第一个竖提,A-L-I-S组成第二个竖提,H-I-R-I组成第三个竖提,最后的N-G组成一个不完整的竖提。
  2. 示例二:
    P-A-Y-P-A-L组成第一个竖提,I-S-H-I-R-I组成第二个竖提,N-G组成最后一个不完成的竖提。

仔细观察,是不是知道了怎么按行数排列字符串了。

排列好字符串以后,我们从左到右,从第一排到最后一排,把数组全部拼接起来即可。

解题思路

目前来看,以作者的水平这个题目没有能够方便使用的算法,只能暴力破解。

  1. 首先确认拼接方式,我们按行数循环,凭借每行的字符,因为题目要求我们从左往右拼接给出结果。
  2. 确认每行中每列字符在字符串中的索引。根据前面的分析,三行的时候四个字符组成一个竖提,也就是说,每次循环需要四个字符,四行的时候六个字符组成一个竖提,我们自己再尝试两行,五行等情况.
    最后你会发现每次循环的字符数 = 2*(num - 1)。 2 = 2*(2-1),4 = 2*(3-1),6 = 2*(4-1),8 = 2*(5-1)。。。。。
  3. 那么我们可以创建num个数组,每个数组 存放一行的内容。
  4. 循环字符串,使用当前下标对当前行数对应的字符数取模,取模的值与行数比较,如果小于行数的,直接使用当前取模值为当前行数。否则使用字符数减去取模值。注意因为我们循环是从0开始,所以这里的实际行数应该加1。比如取模值为0,实际是第一行。
  5. 拼接所有行的字符。

根据以上分析,我们可以编写实现代码。

实际算法代码

以下是暴力解答的代码实现:

public class ZigzagConversion {public static void main(String[] args) {ZigzagConversion solution = new ZigzagConversion();System.out.println(solution.convert("PAYPALISHIRING", 3)); // 输出 "PAHNAPLSIIGYIR"System.out.println(solution.convert("PAYPALISHIRING", 4)); // 输出 "PINALSIGYAHRPI"}public String convert(String s, int numRows) {// 行数是1的矩阵或者行数就等于字符串长度的,直接返回字符串本身if (numRows == 1 || numRows >= s.length()) return s;// 定义一个数组,用来存储每一行的字符串StringBuilder[] rows = new StringBuilder[numRows];// 定义每行的拼接对象,注意行数 = i-1for (int i = 0; i < numRows; i++) {rows[i] = new StringBuilder();}// 获取字符串长度用于循环int n = s.length();// 获取每次循环时构成Z性的字符长度int cycleLen = 2 * numRows - 2;// 循环字符串for (int i = 0; i < n; i++) {// 取模int rowIndex = i % cycleLen;// 小于行数的索引,行数就等于索引,大于的用字符数减取模值,因为此时从下往上排列if (rowIndex < numRows) {rows[rowIndex].append(s.charAt(i));} else {rows[cycleLen - rowIndex].append(s.charAt(i));}}// 拼接结果StringBuilder result = new StringBuilder();for (StringBuilder row : rows) {result.append(row);}return result.toString();}
}

结果

运行程序,正常输出答案:

在这里插入图片描述

提交到力扣,也通过测试:

在这里插入图片描述

总结

又是暴力解答的一题,没有已经归纳好的算法,单纯就是总结规律加上字符串数组循环拼接的基础知识。

善于分析归纳,扎实的基础,基本上没有解不出的题目,暴力解答也是解答,别拿豆包不当干粮,是吧?

准备直面困难题目了,加油!!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com