6. ZigZag Conversion(Medium)

来源:互联网 发布:未来网络的发展方向 编辑:程序博客网 时间:2024/05/17 06:41

一、描述


二、分析

这题的难点在于确定原始zigzag排列形式的字符串在按行读取后,其每个字符对应坐标位置的确定。作为一个业余选手,我将分享下我的解题思路。

题目所给例子的字符串序号如下所示:


根据这个坐标矩阵,更容易理解题目的意思。原字符串的排列是:0-13。按序号读取。现在要将其读取顺序改为0,4,8,12,1,3,5,7……

那么显然问题的关键在于坐标关系。即:每一行的在zigzag排列形式的起始序号,以及每一行第n个元素在zigzag排列形式的位置。

由于行数太少,不太好确定坐标关系,可以将行数改成四行:


顺着箭头,我们可以发现:

第0行:0和6差6 6和12差6

第1行:1和5差4 7和11差4

第2行:2和4差2 8和10差2

...

第i行:相应位置差2*(numRows - i - 1)

再次观察:


顺着箭头,我们可以发现:

第0行:0

第1行:5和7差2 11和13差2

第2行:4和8差4 10和14(假如存在)差4

第3行:3和9差6

...

第i行:相应位置差2*i


有了上诉先验知识,我们可以得到如下结论:

(1)第i行第一个元素位置为i

(2)第i行第n个元素元素位置为i + 2*(numRows - n - 1) 或者 i + 2*n(拐角处)

注意:第0行和numRows - 1行需要另外处理,具体见程序。

三、c++实现

class Solution {public:    string convert(string s, int numRows) {                int length;        length = s.length();                if(length <= numRows ||          numRows == 1)        {            return s;        }                string r;        for(int i = 0; i < numRows; ++i)        {            int j;            int d1, d2;                        j = i;            d1 = 2 * i;            d2 = (i == numRows - 1) ? d1 : 2 * (numRows - i - 1);                        r += s[i];                        while(j + d2 <= length - 1)            {                j += d2;                r += s[j];                                if(i == 0 || i == numRows - 1)                {                    continue;                }                                if(j + d1 <= length - 1)                {                    j += d1;                    r += s[j];                }                else                {                    break;                }            }          }                return r;    }};