zoukankan      html  css  js  c++  java
  • LeetCode ZigZag Conversion

    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".

    class Solution {
    public:
        string convert(string s, int nRows) {
            int len = s.length();
            if (len < 2 || nRows == 1 || len < nRows) return s;
            vector<string> cols;
    
            int si = 0;
            int ri = 0;
            
            while (si < len) {
                bool inacol = cols.size() % (nRows-1) == 0;
                
                if (!inacol) {
                    for (int i=0; i<nRows - 2 && si <len; i++, si++) {
                        cols.push_back(s.substr(si, 1));      // a char as a single column
                    }
                    continue;
                }
                
                cols.push_back(string());
    
                for (int i=0; i<nRows && si<len; i++, si++) {
                    cols.back().push_back(s[si]);   // all char in a column
                }
            }
    
            string res;
            int nCols = cols.size();
    
            int stepa = nRows - 1;
            int stepb = 0;
            
            for (int i=0; i<nRows; i++) {
                bool usea = false;
                int last = -1;
                for (int j = 0; j < nCols; j += usea ? stepa : stepb) {
                    usea = !usea;
                    if (j == last) continue;
                    last = j;
                    
                    int r = i, c = j;
                    
                    if (cols[c].length() < 1) break;
                    
                    if (c % (nRows - 1) != 0) {
                        r = 0;
                    } else if (cols[c].length() - 1 < r) {
                        break;
                    }
                    res.push_back(cols[c][r]);
                }
                --stepa, ++stepb;
            }
            cols.clear();
            return res;
        }
    };

    一般来说那么长,时间又是100ms+的代码定不是好的!

    发现一个以前没注意到的问题,如下代码:

        string a("abc");
        string b;
        b.push_back(a[10]);
        cout<<b.length()<<endl;
    

    编译运行并不会报错,虽然其中a[10]的操作明显越界了,但是与数组不同,字符串的下标操作当越界时会返回一个NULL字符,去http://www.cplusplus.com/查了一下,上面是这么说的:

    If pos is equal to the string length, the function returns a reference to a null character (charT()).

    从实际测试来看,不仅仅是当str[pos]中的pos == str.length()时, 当其大于字符串长度时也是如此。虽然这样的过程是一番好意,但是有时候却让错误变得更难以发现,如下代码:

        string a("abc");
        string b(a);
        b.push_back(a[10]);
        
        cout<<a<<","<<b<<endl;
        cout<<(a == b)<<endl;
    

    输出a, b时,他们是完全一样的,然而因为b比a多了NULL,在等值比较时就不相等了,非常令人困惑。当然根源还是,码农不小心。。。

    第二轮:

    居然写出如此冗长的代码,来个简短版的:

    class Solution {
    public:
        string convert(string s, int numRows) {
            string res;
            if (numRows < 1) {
                return res;
            }
            vector<string> z(numRows);
            int len = s.size();
            int row = 0;
            int delta = numRows == 1 ? 0 : 1;
            for (int i=0; i<len; i++) {
                z[row].push_back(s[i]);
                int next = row + delta;
                if (next == numRows || next == -1) {
                    delta = -delta;
                }
                
                row += delta;
            }
            
            for (string& s : z) {
                res.append(s);
            }
            return res;
        }
    };

     再来一个不用额外空间的

    class Solution {
    public:
        string convert(string s, int numRows) {
            string res;
            if (numRows < 1) {
                return res;
            }
            int len = s.size();
            if (len <= numRows || numRows == 1) {
                return s;
            }
            int delta = 2 * numRows - 2;
            
            for (int i=0; i<numRows; i++) {
                res +=s[i];
                int next = i + delta;
                while (next - 2 * i < len) {
                    if (i != 0 && i != numRows - 1) {
                        res += s[next - 2 * i];
                    }
                    if(next < len) {
                        res += s[next];
                    }
                    next += delta;
                }
            }
            return res;
        }
    };

    快很多

  • 相关阅读:
    Map接口框架图
    Collection接口框架图
    Java集合框架源码(四)——Vector
    Java集合框架源码(三)——arrayList
    HashSet与HashMap的区别
    Java集合框架源码(二)——hashSet
    hashMap与hashTable的区别
    HashMap与ConcurrentHashMap的区别
    asp.net 项目Net4.0 在IE10、 IE 11 下出现 “__doPostBack”未定义 的解决办法
    C# 完整List例子
  • 原文地址:https://www.cnblogs.com/lailailai/p/3918191.html
Copyright © 2011-2022 走看看