【leetcode】6.Z 字形变换

题目

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

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

L   C   I   R
E T O E S I I G
E   D   H   N

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

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"

解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

自己的代码

class Solution {
public:
    string convert(string s, int numRows) {
        	if (s.length() == 0) return "";
	if (s.length() == 1) return s;
	

	string result;
	
	if (s.length() >= 2 && numRows >= 1) {
		int num_one_block = 2 * numRows - 2;
        int group_num;
        if(numRows>=3){
		    group_num = s.length() % num_one_block==0? 
			    s.length() / num_one_block : s.length() / num_one_block+1;
		}else{
            num_one_block=numRows;
            group_num = s.length() % num_one_block==0? 
			    s.length() / num_one_block : s.length() / num_one_block+1;
        }
		for (int i = 0; i < numRows; i++) {
			if (i == 0|| i == numRows - 1) {
				for (int j = 0; j < group_num; j++) {
					if (i + j * num_one_block < s.length())
						result = result + s[i + j * num_one_block];
				};//第一行
			}
			
			else {
				for (int j = 0; j < group_num; j++) {
					if(i+j*num_one_block<s.length())
						result = result + s[i+j*num_one_block];
					if (num_one_block - i + j * num_one_block < s.length())
						result = result + s[num_one_block - i + j * num_one_block];
				}
			}
		}
	}
	return result;  
    }
};

别人的代码

示例1

class Solution {
public:
        string convert(string s, int numRows) {

        if (numRows == 1) return s;

        vector<string> rows(min(numRows, int(s.size())));
        int curRow = 0;
        bool goingDown = false;

        for (char c : s) {
            rows[curRow] += c;
            if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
            curRow += goingDown ? 1 : -1;
        }

        string ret;
        for (string row : rows) ret += row;
        return ret;
    }
};

示例2

class Solution {
public:
    string convert(string s, int numRows) {
        if (numRows == 1) return s;
        
        int len = s.size();
        int rtNcnt = 2 * numRows - 2;
        int Ncnt = (len - numRows) / rtNcnt;
        
        int tail = len - 1;     // 最后一个字符的坐标
        int Nendp = numRows + Ncnt * rtNcnt - 1;    // 最后一个完整'N'的右下角坐标

        string res;
        for (int i = 0; i < numRows; i++)
        {
            // 处理完整的'N'
            res += s[i];
            for (int j = 1; j <= Ncnt; j++)
            {
                if (0 < i && i < numRows - 1)
                    res += s[j * rtNcnt - i];
                res += s[j * rtNcnt + i];
            }

            // 处理多出来的"尾巴"
            if (tail > Nendp)
            {
                int extra = (Ncnt + 1) * rtNcnt;
                if (Nendp < extra - i && extra - i < len)
                    res += s[extra - i];
                if (tail > extra
                        && 0 < i && i < numRows - 1
                        && extra + i < len)
                    res += s[extra + i];
            }
        }

        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值