天天看點

[leetcode] 6. ZigZag Conversion

Description

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 s, int numRows);
           

Example 1:

Input:

s = "PAYPALISHIRING", numRows = 3
           

Output:

"PAHNAPLSIIGYIR"
           

Example 2:

Input:

s = "PAYPALISHIRING", numRows = 4
           

Output:

"PINALSIGYAHRPI"
           

Explanation:

P     I    N
A   L S  I G
Y A   H R
P     I
           

分析

題目的意思是:把字元串轉換成之字形的然後輸出。

比如有一個字元串 “0123456789ABCDEF”,轉為zigzag

當 n = 2 時:

0 2 4 6 8 A C E

1 3 5 7 9 B D F
           

當 n = 3 時:

0   4   8   C

1 3 5 7 9 B D F

2   6   A   E
           

當 n = 4 時:

0      6      C
1    5 7    B D
2  4   8  A   E
3      9      F
           

除了第一行和最後一行沒有中間形成之字型的數字外,其他都有,而首位兩行中相鄰兩個元素的index之差跟行數是相關的,為 2*nRows - 2,

  • 根據這個特點,我們可以按順序找到所有的黑色元素(例如n=4中的第一列)在元字元串的位置,将他們按順序加到新字元串裡面
  • 對于紅色元素出現的位置也是有規律的,每個紅色元素(例如n=4中的第二列)的位置為 j + 2nRows-2 - 2i, 其中,j為前一個黑色元素的列數,i為目前行數。
  • 比如當n = 4中的那個紅色5,它的位置為 1 + 24-2 - 21 = 5,為原字元串的正确位置。
  • 當我們知道所有黑色元素和紅色元素位置的正确算法,我們就可以一次性的把它們按順序都加到新的字元串裡面。

代碼

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

參考文獻

[程式設計題]zigzag-conversion

[LeetCode] ZigZag Converesion 之字型轉換字元串