1. 题目解析
题目链接:6. Z 字形变换
这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。
2.算法原理
想要画出N字形,我们首先要观察并找出其中的规律。假设我们用“row”来代表行数,当row等于4时,N字形的形状如下:
- 第一行:
- 第一个数是0,这是起始点。
- 第二个数是
2row - 2
,即2*4 - 2 = 6
。 - 第三个数是
4row - 4
,即4*4 - 4 = 12
。
- 第二行:
- 第一个数是1,这是行号。
- 接下来的数围绕
2row - 2
的倍数进行取值,即围绕6的左右两边取值。 - 第二个数是
(2row - 2) - 1
,即6 - 1 = 5
。 - 第三个数是
(2row - 2) + 1
,即6 + 1 = 7
。 - 第四个数是
(4row - 4) - 1
,即12 - 1 = 11
。 - 第五个数是
(4row - 4) + 1
,即12 + 1 = 13
,但这里要注意,由于第二行只有五个位置,所以这个数其实应该是9
。
- 第三行:
- 第一个数是2,这是行号。
- 同样,接下来的数也是围绕
2row - 2
的倍数进行取值。 - 第二个数是
(2row - 2) - 2
,即6 - 2 = 4
。 - 第三个数是
(2row - 2) + 2
,即6 + 2 = 8
。 - 第四个数是
(4row - 4) - 2
,即12 - 2 = 10
。 - 第五个数是
(4row - 4) + 2
,但由于第三行也只有五个位置,所以这个数实际上是2
。
- 第四行:
- 第一个数是3,这是行号。
- 接下来的数形成了一个差为
2row - 2
的等差数列。 - 第二个数是
(2row - 2) + 3
,即6 + 3 = 9
,但这里超出范围了,所以实际上是13
。 - 由于第四行只有两个位置,所以只有一个额外的数,即
(4row - 4) + 3
,即12 + 3 = 15
,但这也超出了范围,因此这一行实际上只有一个数3
。
通过上述观察,我们可以得出一个清晰的规律:
- 第一行和第四行是差为
2row - 2
的等差数列。 - 第二行和第三行除了第一个数是行号外,其余数都是围绕
2row - 2
的倍数左右取值。
基于这个规律,我们可以编写一个迭代算法来生成任意行数的N字形。算法会按照上述规律,逐行计算并输出每一行的数字。这样,无论是画一个简单的N字形,还是一个复杂的、包含多行的N字形,我们都可以轻松应对了。
3.代码编写
class Solution
{
public:string convert(string s, int numRows) {// 处理边界情况if(numRows == 1) return s;string ret;int d = 2 * numRows - 2, n = s.size();// 1. 先处理第⼀⾏for(int i = 0; i < n; i += d)ret += s[i];// 2. 处理中间⾏for(int k = 1; k < numRows - 1; k++) // 枚举每⼀⾏{for(int i = k, j = d - k; i < n || j < n; i += d, j += d){if(i < n) ret += s[i];if(j < n) ret += s[j];}}// 3. 处理最后⼀⾏for(int i = numRows - 1; i < n; i += d)ret += s[i];return ret;}
};
The Last
嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。
觉得有点收获的话,不妨给我点个赞吧!
如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~