LeetCode 6 | Z字形变换
题目
题解
- 按行遍历:
思路:分析题目可以发现整个字符串按Z形变换被分成了numRows行(前提:s.size()>numRows),所以我们按照Z形变换的方式一次构建每一行,我们用curRow代表当前所处行,可以发现每当curRows=0或numRows-1是才会改变按行依次构建的遍历方向。
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1)return s;//1相当于没有变换
//防止字符串长度小于非空行个数
int len=s.size()<numRows?s.size():numRows;
vector<string> Vs(len);
//记录遍历行方向
bool goingDown=false;
//当前所处行
int curRows=0;
for(auto c:s){
//按行顺序添加
Vs[curRows]+=c;
//判断行遍历方向是否需要改变
if(curRows==0||curRows==numRows-1){
goingDown=!goingDown;
}
//按行遍历
curRows+=goingDown?1:-1;
}
//待返回结果
string res;
//合并行
for(auto c:Vs){
res+=c;
}
return res;
}
};
- 按行访问:
思路:
按照与逐行读取 Z 字形图案相同的顺序访问字符串。
算法:
首先访问 行 0 中的所有字符,接着访问 行 1,然后 行 2,依此类推…
对于所有整数 k,
行 0 中的字符位于索引k(2⋅numRows−2) 处;
行numRows−1 中的字符位于索引k(2⋅numRows−2)+numRows−1 处;
内部的 行 i 中的字符位于索引 k(2⋅numRows−2)+i 以及 (或)(k+1)(2⋅numRows−2)−i 处;
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) return s;
string ret;
int n = s.size();
int cycleLen = 2 * numRows - 2;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j + i < n; j += cycleLen) {
ret += s[j + i];
if (i != 0 && i != numRows - 1 && j + cycleLen - i < n)
ret += s[j + cycleLen - i];
}
}
return ret;
}
};
- 总结:方法一难想到,方法二规律不好总结。结论:我不会!!我是sb