LeetCode [6. ZigZag Conversion]

Problem: 6. ZigZag Conversion

Question:

The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y   I   R

And then read line by line: “PAHNAPLSIIGYIR”
Write the code that will take a string and make this conversion given a number of rows:

string convert(string text, int nRows);

convert(“PAYPALISHIRING”, 3) should return “PAHNAPLSIIGYIR”.

解题思路:

/*n=numRows
1                           2n-1                         4n-3
2                     2n-2  2n                    4n-4   4n-2
3               2n-3        2n+1              4n-5       .
.           .               .               .            .
.       n+2                 .           3n               .
n-1 n+1                     3n-3    3n-1                 5n-5
n                           3n-2                         5n-4
*/

ZigZag是将字母按照'Z'字形排列过去的一种模式。实际上是盘山公路的“之”字形,ZigZag在英文中就有蜿蜒、盘山公路的意思

了解完ZigZag是什么就可以开始解题了。

目标:解析给定的字符串使得每一行的每个字母依次组合,第一行组完就第二行…最后就形成给定的字符串。

A    G    M
B  F H  L O
C E  I K  P
D    J    Q

从上面的字符串可以找出一点规律,看第一行,A的下一个字母是G,两者间隔的距离是 6 (BCDEF),最后一行也是如此,两个连续字母之间的距离都是相等的,有如下规律。

dis = 2*numRows-2

看中间的字母,B和H的间隔也是6,但B的下一个字母是F,第三行C的下一个字母是E,但是观察可以发现,中间行的第一个字母和第二个字母,第三个字母和第四个字母的间隔相同。(在上面的图中,同一行,不相邻的两个字母”间隔”相同)
设中间行的行数为 i(从1开始计数),有如下规律:

dis = 2*numRows-2-i

所以思路如下:

  1. 第一行和最后一行,result += str[i(当前字母的位置) + dis]
  2. 中间行数,设第一个字母的行数为 i, 则第二字母的位置为 2*numRows-2-i,往后的字母,根据 dis 依次后移可以得到

代码

class Solution {
public:
    string convert(string s, int numRows) {
        if (numRows == 0 || numRows == 1)
            return s;
        string result = "";
        int n = 0, k = 0;
        int cycle = 2*numRows - 2;
        for (int i = 0; i < numRows; i++) {
            for (int j = i; j < s.length(); j = j + cycle) {
                result = result + s[j];
                int second = j - i + cycle - i;
                if (i != 0 && i != numRows - 1 && second < s.length())
                    result = result + s[second];
            }
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值