LeetCode.No6——Z字形变换

5 篇文章 0 订阅
4 篇文章 0 订阅

题目

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L   C   I   RE T O E S I I GE   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

思路

虽然题目说是Z字形,但我理解为N字形。看到题目时,第一时间想到的是递归,经过计算可发现规律,即每次递归时,第一个字符和第二个字符之间的相隔 2n - 3 个字符(n >=2),后来发现提取数组比较麻烦,作罢。
之后很快地想到了桶排序,故用了桶排序。

解法:桶排序解题

  • 算法较为简单易懂,代码有注释。
public class Main {

    public static void main(String[] args) {
	// write your code here
        String s = "Apalindromeisaword,phrase,number,orothersequenceofunitsthatcanbereadthesamewayineitherdirection,withgeneralallowancesforadjustmentstopunctuationandworddividers.";
        int numRows = 3;
        s = convert(s,numRows);
        System.out.println(s);
    }

    public  static String convert(String s, int numRows)
    {
        if(s == null || s.length() == 0 || numRows == 1)//排除一些临界取值
        {
            return s;
        }
        char [] arr = s.toCharArray();//存储转化后的字符数组
        char [] arr_sorted = new char [arr.length];//存储整理后的字符数组
        char [][] bucket = new char [numRows][arr.length/(numRows - 1) + 5];//建立一个二维数组作为桶,这里注意,桶的个数易求,
                                                                            // 但桶的长度较难,容易越界,经过证明可得长度为多少时合适,这里取了一个较为合理的值
        int [] point = new int [numRows];//用于作为每个桶的指针
        int mark = 0;//用于后面的往复标记

        for(int i = 0,j = 0 ;i < arr.length; i ++)//开始将数据倒入桶内
        {
            bucket[j][point[j]] = arr[i];
            point[j] ++;//此处为桶指针的移动
            if(mark == 0){//此处为每个桶的移动,符合N字形规律
                j++;
            }
            else {
                j--;
            }

            if (j == -1) {
                j=1;
                mark = 0;
            }
            else if(j == numRows) {
                j = numRows - 2;
                mark = 1;
            }
        }
        int p = 0;
        for(int j = 0,i = 0;j < numRows ; j ++)//这里将每个桶中的数据倒回数组
        {
            i = 0;
            while (bucket [j][i] != '\u0000')
            {
                arr_sorted[p] = bucket [j][i];
                p ++;
                i ++;
            }
        }
        s = String.valueOf(arr_sorted);
        return s;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值