題目
輸入一個矩陣,按照從外向里以順時針的順序依次打印出每一個數(shù)字爷狈,例如锌云,如果輸入如下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數(shù)字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解題思路
循環(huán)地進行從左到右坡椒,從上到下就缆,從右到左帖渠,從下到上的打印“年輪”上的元素。
難點
怎么確定循環(huán)條件
(1)每一圈打印的起始點都在45°對角線上竭宰,所以可以聲明一個start變量標識起始打印點
(2)由于(start+1)代表已經(jīng)打印的圈數(shù)空郊,2*max{start} < min{rows,columns}怎么確定四條邊的打印前提條件
從左到右:子矩陣至少有一個元素
從上到下:子矩陣至少有兩列
從右到左:子矩陣至少有兩行兩列
從下到上:子矩陣至少有三行兩列怎樣訪問四條邊上元素
由于四條邊的元素,一旦起始點定了之后切揭,其他所有元素的行標和列標范圍也就定了渣淳,因此可以確定endX,endY
endX = columns - 1 - start
endY = rows - 1 - start
從左到右遍歷時,縱坐標保持變?yōu)閥 = start伴箩,橫坐標為x = start:1:endX
從上到下遍歷時,橫坐標保持不變x = endX,縱坐標為y = (start+1):1:endY
從右到左鄙漏,y = endY, x = (endX-1):1:start
從下到上嗤谚,x = start, y = (endY-1):1:(start+1)
有意思的地方
四條邊的打印前提條件具有遞進關系而非并列關系,即一個比一個條件更苛刻
?class Solution {
public:
void PrintMatrixInCircle(vector<vector<int> > &matrix,int start, vector<int> &ret){
int rows = (int)matrix.size();
int columns = (int)matrix[0].size();
int endX = (columns-1) - start;
int endY = (rows-1) - start;
// 從左到右
for(int i = start; i <= endX; ++i){
ret.push_back(matrix[start][i]);
}
// 從上到下怔蚌,至少2行
if(endY > start){
for(int i = start+1;i <= endY;++i){
ret.push_back(matrix[i][endX]);
}
}
// 從右到左巩步,至少2行2列
if(endX > start && endY > start){
for(int i = endX-1; i >= start; --i){
ret.push_back(matrix[endY][i]);
}
}
// 從下到上,至少有3行2列
if(endY > start + 1 && endX > start){
for(int i = endY-1; i >= start + 1; i--){
ret.push_back(matrix[i][start]);
}
}
}
vector<int> printMatrix(vector<vector<int> > matrix) {
int rows = (int)matrix.size();
int columns = (int)matrix[0].size();
vector<int> ret;
if(matrix.size() == 0 || columns <=0 || rows <= 0) return ret;
int start = 0;
while(columns > start*2 && rows > start*2){
PrintMatrixInCircle(matrix,start,ret);
++start;
}
return ret;
}
};