1. 程式人生 > 實用技巧 >6.z字形變換

6.z字形變換

將一個給定字串根據給定的行數,以從上往下、從左到右進行 Z 字形排列。

比如輸入字串為 "LEETCODEISHIRING" 行數為 3 時,排列如下:

之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:"LCIRETOESIIGEDHN"。

方法一

分析:

斜線上的元素在原字串中的下標為j+size-2*i。
    string convert(string s, int numRows) {
        //如果numRows=1,結果就是s
        if(numRows<=1) return s;
        string res;
        int size=2*numRows-2,n=s.size();
        //i表示行號,也是每行開頭元素的下標
        for(int i=0;i<numRows;++i)
            //遍歷每一行
            for(int j=i;j<n;j+=size){
                res+=s[j];
                if(i!=0&&i!=numRows-1&&j+size-2*i<n)
                    res+=s[j+size-2*i];
            }
       return res;
    }

方法二

分析:

也可以用下面這種更直接的方法來做,建立一個大小為 numRows 的字串陣列,為的就是把之字形的陣列整個存進去,然後再把每一行的字元拼接起來,就是想要的結果了。順序就是按列進行遍歷,首先前 numRows 個字元就是按順序存在每行的第一個位置,然後就是 ‘之’ 字形的連線位置了,可以發現其實都是在行數區間 [1, numRows-2] 內,只要按順序去取字元就可以了,最後把每行都拼接起來即為所求。
   string convert(string s, int numRows) {
        if(numRows<=1) return s;
        string res;
        vector<string> v(numRows);
        int n=s.size(),i=0;
        while(i<n){
            //向下遍歷numRows個字元
            for(int pos=0;pos<numRows&&i<n;pos++){
                v[pos]+=s[i++];
            }
            //斜向上遍歷numRows-2個字元
            for(int pos=numRows-2;pos>0&&i<n;pos--){
                v[pos]+=s[i++];
            }
        }
        for(auto s:v) res+=s;
        return res;
    }