6. Z字形變換(leetcode)
將字串 "PAYPALISHIRING" 以Z字形排列成給定的行數: P A H N A P L S I I G Y I R
之後從左往右,逐行讀取字元:"PAHNAPLSIIGYIR"
實現一個將字串進行指定行數變換的函式:
string convert(string s, int numRows);
示例 1:
輸入: s = "PAYPALISHIRING", numRows = 3 輸出: "PAHNAPLSIIGYIR"
示例 2: 輸入: s = "PAYPALISHIRING", numRows = 4 輸出: "PINALSIGYAHRPI"
解釋:
解決方案
方法一:暴力法
比如有一個字串 “0123456789ABCDEF”,轉為zigzag。 當numRows為2時: 0 2 4 6 8 A C E 1 3 5 7 9 B D F
當numRows為3時: 0 4 8 C 1 3 5 7 9 B D F 2 6 A E
當numRows為4時: 0 6 C 1 5 7 B D 2 4 8 A E 3 9 F
我們可以看到,除了第一行和最後一行中間沒有形成之字形的數字外,其餘都有,並且形成的黑色字元之間,列與列之間相鄰的兩個元素的index之差與行數是相關的,都是 2*rows - 2。因此,根據這一個特點,我們可以按順序找到所有的黑色元素在原字串中的位置。對於紅色字元的出現也是有規律的,每一個紅色字元的位置為 j + (2*rows - 2) - 2*i ,其中j為前一個黑色元素所處的列數,i為當前的行數。當我們知道所有黑色元素和紅色元素位置的正確演算法,我們就可以一次性的把它們按順序都加到新的字串裡面。其中程式碼如下:
class Solution { public: string convert(string s, int numRows) { if(numRows <= 1) return s; int len = s.length(); string res = ""; int size = 2*numRows - 2; for(int i=0;i<numRows;i++) { for(int j=i;j<len;j+=size) { res += s[j]; int temp = j + size - 2*i; if(i != 0 && i != numRows-1 && temp < len) res += s[temp]; } } return res; } };
複雜度分析
- 時間複雜度:O(n),每個索引被訪問一次。
- 空間複雜度:O(n)。