• 力扣LeetCode算法题 第6题-Z 字形变换


    要求:

    一开始看到题目,第一想到的思路,就被题目要求的思路给带偏了。

    内容是Z字型输出内容

     就一直想着把字符串输出成上面这种格式

    总是想着把字符串放入到二维数组中进行展示。

    这样一来思路就受到了限制。

    一直使用先写入数组中。

    1. //将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
    2. //比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
    3. public static String convert1(String s, int numRows) {
    4. System.out.println("s.length="+s.length());
    5. //想法和思路。Z字格设计,其实就是把数字一个个放进到二维数组中。再按照顺序去读取出来。
    6. //二维 数组的长度length=s.length/(width-1),width=numRows
    7. int arr_width = numRows;
    8. int arr_length = s.length()/(arr_width-1);
    9. int lie_mark=0;//向右进位标记
    10. int hang_mark=0;//向下进位标记
    11. //根据长度进行生成数组
    12. int[][] arrays = new int[arr_width][arr_length];
    13. //因为Z字写入数据,需要反向写入数据,涉及到了标记。
    14. int flag =-1;//flag==1,则从上往下写。 flag==-1,从下往上写。
    15. // i=0 ,1,2 i=3反向 i=5反向 i =9
    16. int flag_count =0;
    17. //记录结果
    18. int result=0;
    19. if(numRows==1){
    20. return s;
    21. }else {
    22. for (int i = 0; i < s.length(); i++) {
    23. hang_mark=flag_count;
    24. // System.out.println("i="+i);
    25. // System.out.println("lie_mark="+lie_mark);
    26. // System.out.println("hang_mark="+hang_mark);
    27. arrays[hang_mark][lie_mark]=s.charAt(i);
    28. if(flag_count==0 && flag_count==numRows-1){
    29. flag=-flag;//反向
    30. }
    31. //判断什么时候往下写
    32. if(flag==1){//向下输出
    33. flag_count++;
    34. }
    35. //判断什么时候向上斜写,(x+1)(y-1)
    36. if(flag==-1){//向上输出
    37. flag_count--;
    38. lie_mark++;
    39. }
    40. System.out.println("flag_count="+flag_count);
    41. }
    42. }
    43. //测试遍历二维数组
    44. for (int i = 0; i < arr_length; i++) {
    45. for (int j = 0; j < arr_width; j++) {
    46. System.out.print(" " +String.valueOf(arrays[i][j]));
    47. }
    48. System.out.println('\n');
    49. }
    50. return "";
    51. }

    该功能还没写完,还存在测BUG.有待完善。

    而在后续中,又想到一种办法,那就是不去一个个的写入。直接由果推导因。

    我们的最终结果是字符串形式,那么我们就直接用字符串去进行拼接就行。

    1. public static String convert(String s, int numRows) {
    2. //用于接收字符串组
    3. StringBuilder[] results = new StringBuilder[numRows];
    4. //String对象赋值
    5. for (int i = 0; i < numRows; i++) {
    6. results[i]=new StringBuilder();
    7. }
    8. //反向输出标志:
    9. int flag_count=0;//反向计数器。=0或者=numRows-1的时候说明到顶和底了,可以反向
    10. int flag = -1;// =1向下输出,=-1向上输出
    11. //判空
    12. if(numRows==1) return s;
    13. for(int i=0;i
    14. //按照结果意愿来进行存放
    15. results[flag_count].append(s.charAt(i));
    16. //判断顶底,进行反向输出
    17. if(flag_count==0 || flag_count==(numRows-1))
    18. flag=-flag;
    19. //计数器工作,每次循环计数一次
    20. if(flag==1)
    21. flag_count++;//=0向下输出
    22. else
    23. flag_count--;//=1向上输出
    24. }
    25. StringBuilder display = new StringBuilder();
    26. for (int i = 0; i < numRows; i++) {
    27. display.append(results[i].toString());
    28. }
    29. return display.toString();
    30. }

    下面是调试的字符串结果:

    算法解释:

    1.根据flag来进行判断向上输出还是向下输出

    2.根据flag_count来判断顶底,到了顶底进行反向。

    附上所有的代码:

    1. package com.zhm.test;
    2. /**
    3. * @Author bige
    4. * @Date: 2022/11/28 10:37
    5. * @ApiNote:Z 字形变换
    6. */
    7. public class Leetcode_test006 {
    8. //将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
    9. //比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
    10. public static String convert1(String s, int numRows) {
    11. System.out.println("s.length="+s.length());
    12. //想法和思路。Z字格设计,其实就是把数字一个个放进到二维数组中。再按照顺序去读取出来。
    13. //二维 数组的长度length=s.length/(width-1),width=numRows
    14. int arr_width = numRows;
    15. int arr_length = s.length()/(arr_width-1);
    16. int lie_mark=0;//向右进位标记
    17. int hang_mark=0;//向下进位标记
    18. //根据长度进行生成数组
    19. int[][] arrays = new int[arr_width][arr_length];
    20. //因为Z字写入数据,需要反向写入数据,涉及到了标记。
    21. int flag =-1;//flag==1,则从上往下写。 flag==-1,从下往上写。
    22. // i=0 ,1,2 i=3反向 i=5反向 i =9
    23. int flag_count =0;
    24. //记录结果
    25. int result=0;
    26. if(numRows==1){
    27. return s;
    28. }else {
    29. for (int i = 0; i < s.length(); i++) {
    30. hang_mark=flag_count;
    31. // System.out.println("i="+i);
    32. // System.out.println("lie_mark="+lie_mark);
    33. // System.out.println("hang_mark="+hang_mark);
    34. arrays[hang_mark][lie_mark]=s.charAt(i);
    35. if(flag_count==0 && flag_count==numRows-1){
    36. flag=-flag;//反向
    37. }
    38. //判断什么时候往下写
    39. if(flag==1){//向下输出
    40. flag_count++;
    41. }
    42. //判断什么时候向上斜写,(x+1)(y-1)
    43. if(flag==-1){//向上输出
    44. flag_count--;
    45. lie_mark++;
    46. }
    47. System.out.println("flag_count="+flag_count);
    48. }
    49. }
    50. //测试遍历二维数组
    51. for (int i = 0; i < arr_length; i++) {
    52. for (int j = 0; j < arr_width; j++) {
    53. System.out.print(" " +String.valueOf(arrays[i][j]));
    54. }
    55. System.out.println('\n');
    56. }
    57. return "";
    58. }
    59. // 例如对一个4行的
    60. //
    61. // 0 6 12 18
    62. // 1 5 7 11 13 17
    63. // 2 4 8 10 14 16
    64. // 3 9 15
    65. //
    66. // 对于n行的, s中的第i个字符:lie=i%(numrows-1).
    67. // 对余数进行判断
    68. // i%(2n-2) == 0 ----> row0
    69. // i%(2n-2) == 1 & 2n-2-1 ----> row1
    70. // i%(2n-2) == 2 & 2n-2-2 ----> row2
    71. // i%(2n-2) == 3
    72. // ...
    73. // i%(2n-2) == n-1 ----> row(n-1)
    74. // ==>
    75. // 对 k = i%(2n-2)进行判断
    76. // k<=n-1时候,s[i]就属于第k行
    77. // k>n-1时候,s[i]就属于2n-2-k行
    78. // 最后将rows拼接起来就行了
    79. public static String convert(String s, int numRows) {
    80. //用于接收字符串组
    81. StringBuilder[] results = new StringBuilder[numRows];
    82. //String对象赋值
    83. for (int i = 0; i < numRows; i++) {
    84. results[i]=new StringBuilder();
    85. }
    86. //反向输出标志:
    87. int flag_count=0;//反向计数器。=0或者=numRows-1的时候说明到顶和底了,可以反向
    88. int flag = -1;// =1向下输出,=-1向上输出
    89. //判空
    90. if(numRows==1) return s;
    91. for(int i=0;i
    92. //按照结果意愿来进行存放
    93. results[flag_count].append(s.charAt(i));
    94. //判断顶底,进行反向输出
    95. if(flag_count==0 || flag_count==(numRows-1))
    96. flag=-flag;
    97. //计数器工作,每次循环计数一次
    98. if(flag==1)
    99. flag_count++;//=0向下输出
    100. else
    101. flag_count--;//=1向上输出
    102. }
    103. StringBuilder display = new StringBuilder();
    104. for (int i = 0; i < numRows; i++) {
    105. display.append(results[i].toString());
    106. }
    107. return display.toString();
    108. }
    109. // 0 6 12 18
    110. // 1 5 7 11 13 17
    111. // 2 4 8 10 14 16
    112. // 3 9 15
    113. public static void main(String[] args) {
    114. //String s = "0123456789876543210";
    115. String s = "PAYPALISHIRING";
    116. //convert(s,3);
    117. System.out.println("result = " + convert1(s,3));
    118. }
    119. }

  • 相关阅读:
    求解答,并希望告知解决方案。
    Mysql数据库基础知识总结,结构分明,内容详细
    TCP 加速小记
    计算机毕业设计之java+SSM酒店客房预定管理系统
    kubectl 本地远程链接k8s多个集群,远程管控多集群,查看日志 部署服务(windows版)
    Git学习:共享仓库多人协作开发
    通过Shell脚本自动安装Hive&JDBC测试&提供CDH5网盘地址
    Linux中安装Jenkins
    保险行业大洗牌,250万线下从业人员消失的背后逻辑
    linux核心知识梳理
  • 原文地址:https://blog.csdn.net/feipo_zhm/article/details/128098238