题目:
将一个给定字符串 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 <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
结果:
方法一:构造图之后读取
方法二:哈希表
解题思路:
方法一:构造图之后读取
1,首先构造一个零时用于换顺序的表
2,将s数组中的数字,按照z型存储到标中
3,读取表中不为初始化的字符的内容
方法二:哈希表
构造一个和s等长的哈希表,其存储该位置的字母应当在第几行
由此可以清楚知道 字符串 s 的每一个字符应当存储的行数。
再循环从应存储在第一行的数据看是取。
如:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
hash | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 |
s | P | A | Y | P | A | L | I | S | H | I | R | I | N | G |
此例子中numRows为4,hash对应内容就是0~3.
最红我们是按照每一个行开始读取,因此先按照顺序将 hash为0的数据取出:
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
hash | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 |
s | P | A | Y | P | A | L | I | S | H | I | R | I | N | G |
retArr | P | I | N |
然后再将 hash值为1的存到后面
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
hash | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 | 2 | 3 | 2 | 1 | 0 | 1 |
s | P | A | Y | P | A | L | I | S | H | I | R | I | N | G |
retArr | P | I | N | A | L | S | I | G |
以此类推。
代码:
方法一:构造图之后读取
char * convert(char * s, int numRows){
int len = strlen(s);
if (numRows == 1 || len == 1) {
return s;
}
char **tempArr = (char **)malloc(sizeof(char *) * numRows);
for (int i = 0; i < numRows; i++) {
tempArr[i] = (char *)malloc(sizeof(char) * len);
for (int j = 0; j < len; j++) {
tempArr[i][j] = '\0';
}
}
int m = 0;
int n = 0;
int upOrDown = 0; // 0表示上升,1表示下降
tempArr[0][0] = s[0];
for (int i = 1; i < len; i++) {
if(m == 0) {
// 已回到第一行准备开始上升
m += 1;
tempArr[m][n] = s[i];
upOrDown = 0;
} else if (m == numRows - 1) {
m -= 1;
n += 1;
tempArr[m][n] = s[i];
upOrDown = 1;
} else {
if(upOrDown == 0) {
m += 1;
tempArr[m][n] = s[i];
} else {
m -= 1;
n += 1;
tempArr[m][n] = s[i];
}
}
}
char *retArr = (char *)malloc(sizeof(char) * (len + 1));
int index = 0;
for(int i = 0; i < numRows; i++) {
for(int j = 0; j < len; j++) {
if(tempArr[i][j] != '\0') {
retArr[index++] = tempArr[i][j];
}
}
}
retArr[index] = '\0';
return retArr;
}
方法二:
char * convert(char * s, int numRows){
int len = strlen(s);
if (numRows == 1 || len == 1) {
return s;
}
char *retArr = (char *)malloc(sizeof(char) * (len + 1));
int *hash = (int *)malloc(sizeof(int) * len);
int upOrDown = 0; // 0表示up,1表示down
int temp = 0;
for (int i = 0; i < len; i++) {
if (upOrDown == 0) {
hash[i] = temp++;
if(temp == numRows) {
temp -= 2;
upOrDown = 1;
}
} else {
hash[i] = temp--;
if(temp < 0) {
temp += 2;
upOrDown = 0;
}
}
}
int index = 0;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < len; j++) {
if(hash[j] == i) {
retArr[index++] = s[j];
}
}
}
free(hash);
retArr[index] = '\0';
return retArr;
}