Zigzag Conversion

The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

And then read line by line: “PAHNAPLSIIGYIR”

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = “PAYPALISHIRING”, numRows = 3
Output: “PAHNAPLSIIGYIR”

Example 2:

Input: s = “PAYPALISHIRING”, numRows = 4
Output: “PINALSIGYAHRPI”
Explanation:

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

package com.zc.algorithm;

import java.util.ArrayList;
import java.util.List;

public class ZigZag {
    /**
     * 通过在集合中创建三个StringBuilder,将每次读取到的字符放入list集合的StringBuilder对象中
     * @param s
     * @param numRows
     * @return
     */
    public static String convert1(String s, int numRows)
    {
        if(numRows == 1) return s;
        //创建一个List集合,保存numRows个StringBuilder对象
        List<StringBuilder> list = new ArrayList<>();
        for(int i = 0; i < numRows;i++)
        {
            list.add(new StringBuilder());
        }
        int currRow = 0;
        boolean goingDown = false;
        for(int i = 0; i < s.length(); i++)
        {
            list.get(currRow).append(s.charAt(i));
            //当currRow = 0或者 currRow = numRows时,改变goingDown的取值
            if(currRow == 0 || currRow == numRows - 1) goingDown = !goingDown;
            currRow += goingDown? 1:-1;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder sb : list)
        {
            res.append(sb);
        }
       return res.toString();
    }

在这里插入代码片

    /**
     * 根据字符串的索引值来读取
     * 举例:L E E T C O D E I S  H  I  R  I  N  G
     * 索引:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
     * 这个字符串的Z字形为:
     * 0    4     8       12
     * 1 3  5  7  9   11  13  15
     * 2    6    10       14
     * 根据以上结果,以及给定的输出行数可得如下规律:
     * 第0行:           (2 * numsRow - 2) * k  (k = 0,1,2........)
     * 第numsRow- 1 行: (2 * numsRow - 2) * k + numsRows - 1
     * 中间行:          前一个数:(2 * numsRow - 2) * k +i  后一个数:(2 * numsRow - 2) * k - i (注意:i 表示中间第几行)
     * @param s
     * @param numsRow
     * @return
     */
    public static String convert2(String s , int numsRow)
    {
        if(numsRow == 1) return s;
        int len = s.length();
        int cycle = 2 * numsRow - 2;
        StringBuilder res = new StringBuilder();
        for(int i = 0; i < numsRow; i++) // 控制行数
        {
            for(int j = 0; j + i< len; j += cycle)
            {
                //当numsRow = 3 时,i = 2,即 numsRows - 1;
                res.append(s.charAt(j + i));
                //中间行是执行这段代码
                if(i!=0 && i != numsRow - 1 && j+cycle - i < len)
                {
                    res.append(s.charAt(j+cycle-i));
                }
            }
        }
        return res.toString();
    }

    public static void main(String[] args)
    {
        String s = "LEETCODEISHIRING";
        System.out.println("使用方法1获取的结果");
        System.out.println(convert1(s,3));
        System.out.println("使用方法2获取的结果");
        System.out.println(convert2(s,3));
    }
}

 /**
     * 这个方法可以理解为双指针法
     * @param s
     * @param numRows
     * @return
     */
   public static String convert3(String s , int numRows)
   {
       if(numRows == 1) return s;
       int len = s.length();
       List<StringBuilder> list = new ArrayList<>();
       for(int i =0 ; i < Math.min(numRows,s.length()); i++)
       {
           list.add(new StringBuilder());
       }
       int i = 0;//根据i获取字符串中的字符
       while(i < len)
       {
           //idx控制行数
           for(int idx = 0 ; i < len && idx < numRows; i++, idx++)
           {
               list.get(idx).append(s.charAt(i));
           }
           //回到中间行
           for(int idx = numRows-2; idx>=1&&i<len; idx--,i++)
           {
               list.get(idx).append(s.charAt(i));
           }
       }
       StringBuilder sb = new StringBuilder();
       for(StringBuilder str : list)
       {
           sb.append(str);
       }
       return sb.toString();
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值