字符串-Z 字形变换

/*
 * @lc app=leetcode.cn id=6 lang=java
 *
 * [6] Z 字形变换
 */

// @lc code=start
class Solution {
    public String convert(String s, int numRows) {

    	/***
    	 EG. 
    		输入:s = "PAYPALISHIRING", numRows = 3
			输出:"PAHNAPLSIIGYIR"
			示例 2:
			输入:s = "PAYPALISHIRING", numRows = 4
			输出:"PINALSIGYAHRPI"
			解释:
			P     I    N
			A   L S  I G
			Y A   H R
			P     I
		
		分析:
			1.这个例子可以分成3个组:
				Group 1:
				 	P    
					A   L
					Y A  
					P    
				Group 2:
					I   
					S  I
					H R
					I	
				Group 3:
					N
					G
			2.每一个组的特征:
				a.完整的组(1,2group)
					(1)第一行、最后一行一个元素;
					(2)其它行两个元素
				b.不完整的组(3group)
					(1)一定存在第一行,其它行存在可能存在
			3.设计代码:
				a.考虑特殊情况当	numRows为1时可以直接返回原字符串
				b.计算组数(groupSize)
				c.设计两层循环
					(1)第一层循环numRows次
					(2)第二层循环groupSize次
				d.第二层循环groupSize次
					(1)计算出当前组和下一组的起始下标
					(2)处理当前组的第一行(这里不用判断下标范围)
					(3)处理当前组的最后一行(这里需要判断下标范围)
					(4)处理当前组的其它行根据上面的分析一般有两列,当如果下标范围出界可以直接跳出循环	
     	 */

    	// For numRows is 1
        if(numRows == 1)
            return s;
            
        int strLen = s.length();
        
        // Group by (numRows + (numRows - 2))
        int groupLen = numRows + (numRows - 2);

        // Get the actual group size
		// Part1: Cal group size        
        // int groupSize = strLen / groupLen;
        // Part2: Get the last group length
        // int lastGroupLen = strLen % groupLen;
        final int groupSize = (strLen / groupLen) + ((strLen % groupLen != 0) ?  + 1 : 0);
        
        StringBuilder resultSB = new StringBuilder();
        
        // Cycle numRows times stands for the per row
        for(int i = 0; i < numRows; i++){
			// Cycle numRows times stands for the per column(like per group)
            for(int j = 0; j < groupSize; j++){
                // This group start index
                int groupStartInd = j * groupLen;
                // This group start index
                int nextGroupStartInd = (j + 1) * groupLen;
        
                // Head of group record one
                if(i == 0){
                    resultSB.append(s.charAt(groupStartInd + i));
                    continue;
                }
        
                // Tail of group record one
                if(i == numRows - 1 && groupStartInd + i < strLen){
                    resultSB.append(s.charAt(groupStartInd + i));
                    continue;
                }
        
                // Middle part record two
                if(groupStartInd + i >= strLen)
                    continue;
                resultSB.append(s.charAt(groupStartInd + i));
                if(nextGroupStartInd - i >= strLen)
                    continue;
                resultSB.append(s.charAt(nextGroupStartInd - i));
            }
        }

        return resultSB.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值