Leetcode Algorithm 006. ZigZag Conversion

来源:互联网 发布:网络研修日志 编辑:程序博客网 时间:2024/05/14 10:02

Leetcode Algorithm 006. ZigZag Conversion

ZigZag Conversion
给定一个字符串,按照规定的zigzag走法排列之后,按行取出字符形成一个新的字符串

解题思路

首先要明白zigzag走法是什么意思。
题目给了我们一个例子:"PAYPALISHIRING"用了3行的zigzag走法会是:

P   A   H   NA P L S I I GY   I   R

看起来还是不太懂?现在画一个4行的zigzag走法:

P     I     NA   L S   I GY A   H RP     I

5行的zigzag走法:

P       HA     S IY   I   RP L     I GA       N

这样是不是清楚多了?Zigzag走法其实就是先走满一列,再沿着斜线方向往回走,走到第一行再次往下走。

其实我们可以找到其中原本字符串在zigzag走法中规律:

0       81     7 92   6   10    ...3 5     11 134       12
0              2n-21         2n-3 2n-1...   ...      ...       ...n-2 n          3n-4 3n-2n-1            3n-3

假设原本的字符串是s,经过n行的zigzag走法之后,某行的行号是i,那么行首的元素将会是s[i]。第i行的下一个元素通过两个间隔来决定,一个是step1 = 2*n - 2 - 2*i,另外一个是step2 = 2*i。知道这条数学规律之后,我们可以很容易地处理它了。

要注意的是当step1或者step2为0的时候恰好是第0行和第n-1行,要做特殊处理。
另外,当n==1或者n>=s.size()的时候无需进行zigzag处理,直接返回原来的字符串即可。

代码

#include<iostream>using namespace std;class Solution {public:    string convert(string s, int numRows) {        int length = s.size();        if (numRows == 1 || numRows >= length)            return s;        string result = "";        for (int i = 0; i < numRows; i++) {            int index = i;            int step1 = 2 * numRows - 2 - 2 * i;            int step2 = 2 * i;            if (index >= length)                break;            result += s[index];            while (true) {                if (step1 != 0) {                    index += step1;                    if (index < length)                        result += s[index];                    else                        break;                }                if (step2 != 0) {                    index += step2;                    if (index < length)                        result += s[index];                    else                        break;                }            }        }        return result;    }};

测试样例

int main() {    Solution s;    cout << s.convert("AB", 3) << endl;    cout << s.convert("PAYPALISHIRING", 5) << endl;    cout << s.convert("PAYPALISHIRING", 4) << endl;    cout << s.convert("PAYPALISHIRING", 3) << endl;    cout << s.convert("PAYPALISHIRING", 2) << endl;    cout << s.convert("PAYPALISHIRING", 1) << endl;    return 0;}

输出

ABPHASIYIRPLIGANPINALSIGYAHRPIPAHNAPLSIIGYIRPYAIHRNAPLSIIGPAYPALISHIRING