ZigZag Conversion
[Problem Link]
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
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
Solution 1
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) return s;
int x = 2*numRows - 2;
int length = s.length();
string ans = "";
for (int i = 0; i < numRows; i++) {
int count = 0;
while(1) {
int first = count*x - i;
int second = count*x + i;
if (first < length && first >= 0) {
ans = ans + s[first];
} else if (first >= 0) {
break;
//一開始沒有考慮到小於0的情況導致會嘗試s[-1],本地跑不會報錯,正確輸出。而在leetcode上面就是wrong answer,leetcode會自動停止並不報錯。
}
if ((second) < length && i != 0 && i != numRows-1) {
ans = ans + s[second];
}
count += 1;
}
}
//cout << ans;
return ans;
}
};
不考慮到first小於0時,在leetcode上run會出現下面這種奇怪的情況。明明是輸出ans後馬上return ans,輸出的值和return的值卻不一樣。初步考慮的原因是leetcode編譯的原因。
Solution 2
class Solution {
public:
string convert(string s, int numRows) {
//if (numRows == 1) return s;
int x = 2*numRows - 2;
int length = s.length();
string ans = "";
for (int i = 0; i < numRows; i++) {
for (int j = 0; j + i < length; j += x) {
ans += s[i+j];
if (i != 0 && i != numRows - 1 && (j+x-i) < length) {
ans += s[j+x-i];
}
}
//cout << ans << ';';
}
return ans;
}
};
Summary
- 上面兩種解法思路是一致的,只是第二種可讀性更強,這道題要點就是找到規律,第一行出現的值的下標週期爲。需要注意的是當n爲1時,週期爲0,就一直再第一個數值處循環,所以需要將n=1的情況單獨處理。
- 需要注意的是,string.length()返回的是無符號數,所以當負數與其進行比較時,會出現-1>string.length()這樣的情況,因爲計算機在遇到有符號數與無符號數進行運算時,會默認將有符號數當成無符號數處理,這點需要注意!
- solution2中要先考慮豎排的數再考慮它右邊是否存在斜排的數,一開始沒想清楚,先考慮豎排數再考慮它左邊是否存在斜排的數,導致最後一部分的數會漏掉,因爲豎排數不存在直接略過了左邊的斜排數。