持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。
6:Z 字形变换
题意
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N A P L S I I G Y I R 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"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.length <= 1000s由英文字母(小写和大写)、','和'.'组成1 <= numRows <= 1000
题解一:二维数组模拟
直接按照题意模拟,将之字形排列输出到二维矩阵中,然后从左到右、从上到下遍历即可。
需要注意,只有一行的情况需要特判,直接输出s。
C++代码:
class Solution {
public:
char a[1010][1010];
string convert(string s, int numRows) {
if(numRows==1) return s;
int x=0,y=1,cnt=0,t=0;
for(int i=1;i<=1000;i++) for(int j=1;j<=1000;j++) a[i][j]=' ';
int n=s.length();
//先输出第一行
while(cnt<numRows&&cnt<n) a[++x][y]=s[cnt++];
while(cnt<n){
//斜着输出
t=0;
while(cnt<n&&t<numRows-1){
a[--x][++y]=s[cnt++];
t++;
}
//输出一列
t=0;
while(cnt<n&&t<numRows-1) a[++x][y]=s[cnt++],t++;
}
string ans=s;cnt=0;
for(int i=1;i<=numRows;i++){
for(int j=1;j<=y;j++){
if(a[i][j]==' ') continue;
ans[cnt++]=a[i][j];
}
}
return ans;
}
};
题解二:巧妙模拟
C++代码:
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1) return s;
vector<string> ve(numRows);
int n=s.length();
int x=0,flag=-1;
for(int i=0;i<n;i++){
ve[x]+=s[i];
if(x==0||x==numRows-1) flag=-flag;
x+=flag;
}
string ans;
for(auto &str:ve) ans+=str;
return ans;
}
};