[C++]LeetCode: 11 ZigZag Conversion

来源:互联网 发布:php接收post文件 编辑:程序博客网 时间:2024/05/16 08:31

题目:

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   NA P L S I I GY   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".

算法复杂度:O(n)

思路:只遍历一次字符串s,就得到目标字符串。关键是怎么得到offset,以及offset如何使用,用法很巧妙!!

Attention: 用pos < len和 pos +offset < len来作为判断循环是否结束的条件。

AC Code:

class Solution {public:    string convert(string s, int nRows) {        if (nRows <= 1)             return s;    string str;    int pos = 0;    int len = s.length();    int offset = 0;    for (int i = 0; i < nRows; i++)    {              //for each row, find the elements and add to string str        pos = i;        //太巧妙了,此处就是i + offset 刚好得到和i同行的字符。实际就是 mod - 2*i =2(nRows-1 - i),画图可知。        offset = 2 * (nRows - 1 - i);           //此处刚好循环 len/2*nRows次 所以算法复杂度是 O(nRows * len/2*nRows) = O(n)        while (pos < len)        {               //which mean str = str + s[pos]             str += s.substr(pos, 1);                  if (i != 0 && i != nRows - 1 && pos + offset < len)            //if it's not the first or last line, we need add one more,                str += s.substr(pos + offset, 1);  //that is str = str + s[pos+offset]            pos += 2 * nRows - 2;        }    }        return str;    }};

解法二: 

算法复杂度:O(nRows*n)

思路://字符串按照Z字型书写,由输入行数决定Z的宽度。要求输出Z字型结果。
        //利用同行的余数相同的原理,遍历得到返回结果result. 其实也是取余后距离nRows-1相同的点在同一行
        //余数: c = a/b;  余数 r = a - c*b.

Attention: 注意是s中字符索引余数相同,而不是s[j]取余相等!!书写时不要想当然顺手就写。

AC Code:

class Solution {public:    string convert(string s, int nRows) {        //字符串按照Z字型书写,由输入行数决定Z的宽度。要求输出Z字型结果。        //利用同行的余数相同的原理,遍历得到返回结果result. 其实也是取余后距离nRows-1相同的点在同一行        //余数: c = a/b;  余数 r = a - c*b.                string result;        if(nRows <= 1)            return s;        int ind = s.length() - 1;        int mod = 2 * nRows - 2;   //nRows大于1时,循环的模是 n +(n-2),归纳总结可得。                //把取余后余数相同的字符或符合互补条件的字符按顺序依次存入result中        //for(int i == 0; i <= mod/2; i++)        for(int i = 0; i <= nRows - 1; i++)        {            for(int j = 0; j <= ind; j++)            {                /*  此处表达有问题,应该是s中对应索引的模,而不是s中元素。思考时对的,但是敲代码时犯了经验错误,顺手写了s[j]                if((s[j] % mod) == i || ((s[j] % mod) + i == mod ))                */                if(j % mod == i || (j % mod) + i == mod)                    result.push_back(s[j]);            }        }        return result;    }};


0 0
原创粉丝点击