【LeetCode】ZigZag Conversion(Z 字形变换)

这道题是LeetCode里的第6道题。

题目要求:

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

题目虽然很长,但是题目本身并不难,却相当的花时间。这道题l类似于我之前做过的螺旋矩阵(回形取数),打打草稿发现规律,找出函数关系就行了。

拿例子2说明:

输入:s = “LEETCODEISHIRING”,numRows = 4

Z字排列如下:

\begin{matrix} & & & & & & & & & & & & \\ & & & & & & & & & & & & \\ & & & & & & & & & & & & \\ & & & & & & & & & & & & \end{matrix}\begin{matrix} L&&&D&&&R\\ E&&O&E&&I&I\\ E&C&&I&H&&N\\ T&&&S&&&G \end{matrix}

转换成对应的下标索引为:

\begin{matrix} 0&&&6&&&12\\ 1&&5&7&&11&13\\ 2&4&&8&10&&14\\ 3&&&9&&&15 \end{matrix}

首先可以发现第一行的索引添加量和Z字的行数numRows有关系:IndexAdd=2*numRows-2

例如当 numRows = 3 时:

\begin{matrix} 0&&4&&8\\ 1&3&5&7&9\\ 2&&6&&10 \end{matrix}

IndexAdd=2*3-2=4

根据这个特性首先可以解决第一行,同理解决最后一行。

解决完首尾行后中间行怎么办呢?因为中间行有斜对角的字符,要如何处理?其实不难,拿例子2来说,第二行17中间一个,713中间一个,第三行28中间一个,814中间一个,也就是说中间行每隔 IndexAdd 就会有一个字符,前提是不超出范围。numRows = 3 时,中间第二行也符合这个规律。而且这些字符还符合另一规律:例子2中5i=1 行(索引值),1和5差44i=2行(索引值),2和4差2。也就是说中间字符和左边字符的差值为 IndexAdd-2*i,所以中间行这样处理:第一个是 j=i,然后中间字符 j=j+IndexAdd-2*i,再是 j=j+2*i,这样走完一轮相当于 j=j+IndexAdd,一直循环。

说明:i 是行的索引值,不是第 i 行。第一行的索引值为0,第二行的索引值为1,等等。

提交代码:

class Solution {
public:
    string convert(string s, int numRows) {
        int i=0,j,len=s.length(),IndexAdd=(numRows-1)*2;
        if(numRows==1||numRows>=s.length())return s;
        string res;
        while(1){
            j=i;
            if(i==0||i==numRows-1){
                while(j<len){res+=s[j];j=j+IndexAdd;}
                i++;
                if(i==numRows)break;
            }else{
                while(j<len){res+=s[j];j=j+IndexAdd-2*i;
                    if(j<len){res+=s[j];j=j+2*i;}}
                i++;
            }
        }
        return res;
    }
};

提交结果:

个人总结:

题目不难只要发现其中规律就能很好的解决。一开始处理的时候弄混淆了下标和字符的关系,浪费了些时间。

posted @ 2019-01-31 23:57  1000sakura  阅读(143)  评论(0编辑  收藏  举报