其实是周三的第三题,打鸡血写了一道中等题,通过画表格,找到规律,虽然解题用了一个半小时,但是自己找到了规律并且把代码敲出来一次过了,而且时空表现都很好,还是很开心hhhh
【题目描述】
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
【示例】
示例 1:
输入: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
示例 3:
输入:s = “A”, numRows = 1
输出:“A”
提示:
1
≤
s
.
l
e
n
g
t
h
≤
1000
,
s
由
英
文
字
母
(
小
写
和
大
写
)
、
′
,
′
和
′
.
′
组
成
1 \le s.length \le 1000,s 由英文字母(小写和大写)、',' 和 '.' 组成
1≤s.length≤1000,s由英文字母(小写和大写)、′,′和′.′组成
1
≤
n
u
m
R
o
w
s
≤
1000
1 \le numRows \le 1000
1≤numRows≤1000
【解答】
【思路】
看到这个题,首先想到的就是找规律,画出排列后每个字符在原字符串中的下标的分布情况,就蛮容易找到规律的。
如下:
可以发现,所有字符的排列可以分组,每组包含t=2*(numRows-1)个元素。第一行每个元素的值都是t的整数倍,最后一行的值都是第一行元素+numRows-1。此外,对每一组,除了第一行和最后一行,每组都有两个元素,而且这两个元素和第一行含特殊规律的下标有关系,代码就很好写了。
写代码时,发现可以先处理特殊情况,可以减少一些运行时间。
【代码】
下面是最后通过的代码:
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1) return s;
else if(s.size()<numRows) return s;
int t=2*(numRows-1);
int len=s.size();
string ans="";
for(int k=0;k<numRows;k++){//逐行输出
if(k==0){//第一行,一组一个
for(int j=0;j<=len/t;j++){
if(t*j < (len)){
ans+=s[t*j];
}
}
}
else if(k==numRows-1){//最后一行,也是一组一个
for(int j=0;j<=len/t;j++){
if(t*j+k < (len)){
ans+=s[t*j+k];
}
}
}
else{ //其他行,每组两个
for(int j=0;j<=len/t;j++){
if(t*j+k <(len)){
ans+=s[t*j+k];
}
if((t*(j+1)-k) < (len)){
ans+=s[t*(j+1)-k];
}
}
}
}
return ans;
}
};
执行结果: