LeetCode(54) SpiralMatrix
来源:互联网 发布:linux kernel启动参数 编辑:程序博客网 时间:2024/06/13 02:55
题目如下:
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
分析如下:
题目的意思是,按照顺时针方向旋转着遍历矩阵,把遍历结果返回。关键是怎么理解旋转的含义?
可以这样来思考。以上面的矩阵为例。
step one: 1,2
step two: 3,6
step three: 9,8
step four: 7,4
这样完成了对最外层的遍历,剥去一层之后(leetcode官网上说,想象剥洋葱那样剥去一层),继续往下剥,去掉次外层,不断进行下去,直到边界条件。显然边界条件是最后只剩1个点,或者一行,或者一列,导致没法拐个弯形成一个矩形。
那么边界条件是什么时候可能发生呢?这是本题最坑爹的地方了,我在这里写了很久才找到正确的边界条件判断语句。
需要写几个4*4, 4*6, 4*2, 5*5, 5*3, 5*7, 4*5, 4*3, 5*4, 5*6例子自己看看,这样才能看出来。
结合看上面的图,可以知道,
1 在rowcount 和colcount中选较小值。到底剥洋葱剥了几层由较小值决定。
2 如果较小值是奇数,那么剥洋葱到最后会产生一条单独的线段。如果较小值是偶数,然么剥洋葱到最后就会完成所有点的打印,不会留有单独的线段。
上面的做法是顺着题意思考的做法,思考边界条件的地方非常坑爹。
还有一种做法是递归,参见leetcode官网的解释,代码量顿时减少很多,虽然时间慢一些,但是本题的递归并没产生太多重复的计算,所以时间空间的开销都是可以忍的。
我的代码:
// 4ms过大集合class Solution {public: vector<int> spiralOrder(vector<vector<int> > &matrix) { vector<int> res; int row=(int)matrix.size(); if(row==0) return res; int col=(int)matrix[0].size(); if(col==0) return res; int count=row<col?row:col; for(int i=0;i<count/2;i++){ for(int j=i;j<col-1-i;j++) res.push_back(matrix[i][j]); for(int j=i;j<row-1-i;j++) res.push_back(matrix[j][col-i-1]); for(int j=col-1-i;j>i;j--) res.push_back(matrix[row-1-i][j]); for(int j=row-1-i;j>i;j--) res.push_back(matrix[j][i]); } //单独处理在最后可能出现的单列或者单行的情况 if(row%2==1&&col%2==1){ //行数为奇,列数为奇,必然需要处理单行或单列 if(row<=col){ for(int i=0;i<=col-row;i++) res.push_back(matrix[row/2][row/2+i]); }else{ for(int i=0;i<=row-col;i++) res.push_back(matrix[col/2+i][col/2]); } }else if(row%2==1&&col%2==0){ //行数为奇,列数为偶,仅当row<col才需要处理单行或单列 if(row<col){ for(int i=0;i<=col-row;i++) res.push_back(matrix[row/2][row/2+i]); } }else if(row%2==0&&col%2==1){//行数为偶,列数为奇,仅当col<row才需要处理单行或单列 if(col<row){ for(int i=0;i<=row-col;i++) res.push_back(matrix[col/2+i][col/2]); } } return res; }};
//leetcode官网解答void print_spiral(int mat[][N_MAX], int m, int n, int k) { if (m <= 0 || n <= 0) return; if (m == 1) { for (int j = 0; j < n; j++) cout << mat[k][k+j] << " "; return; } if (n == 1) { for (int i = 0; i < m; i++) cout << mat[k+i][k] << " "; return; } // print from top left for (int j = 0; j < n - 1; j++) cout << mat[k][k+j] << " "; // print from top right for (int i = 0; i < m - 1; i++) cout << mat[k+i][k+n-1] << " "; // print from bottom right for (int j = 0; j < n - 1; j++) cout << mat[k+m-1][k+n-1-j] << " "; // print from bottom left for (int i = 0; i < m - 1; i++) cout << mat[k+m-1-i][k] << " "; print_spiral(mat, m-2, n-2, k+1);} void print_spiral_helper(int mat[][N_MAX], int m, int n) { print_spiral(mat, m, n, 0);}
题目小结:
(1) 这道题写了很久才写出来。首先是没有想到用递归,如果用递归,可以很快写出来。其次是,就算没有想到用递归,那么迭代版依然花了很长时间,这里面的时间大量花费在没有真正想清楚边界条件就去着急写code了。所以如果没有想清楚,不要着急写。最省时间的方式是先想清楚了再写。
update: 2015-01-10
//4ms class Solution {public: vector<int> spiralOrder(vector<vector<int> > &matrix) { vector<int> res; int nRow = matrix.size(); if (nRow == 0) return res; int nCol = matrix[0].size(); if (nCol == 0) return res; if (nRow == 1) return matrix[0]; if (nCol == 1) { for (int i = 0; i < nRow; ++i) res.push_back(matrix[i][0]); return res; } int offset_range = nRow < nCol ? nRow/2 : nCol/2; for (int offset = 0; offset < offset_range; ++offset) { // up for (int i = offset; i < nCol - offset - 1; ++i) { res.push_back(matrix[offset][i]); } // right for (int i = offset; i < nRow - offset - 1; ++i) { res.push_back(matrix[i][nCol - offset - 1]); } //down for (int i = nCol - offset - 1; i >= 1 + offset; --i) { res.push_back(matrix[nRow - offset - 1][i]); } //left for (int i = nRow - offset - 1; i >= 1 + offset; --i) { res.push_back(matrix[i][offset]); } } if (nRow < nCol && nRow % 2 == 1) { for (int i = offset_range; i < nCol - offset_range; ++i ) { res.push_back(matrix[nRow/2][i]); } } else if (nRow >= nCol && nCol %2 == 1) { for (int i = offset_range; i < nRow - offset_range; ++i) { res.push_back(matrix[i][nCol/2]); } } return res; }};
这道题目还有续集 Spiral Matrix II,其实本质是同一道题目。
- LeetCode(54) SpiralMatrix
- LeetCode(57) SpiralMatrix II
- spiralMatrix
- LeetCode 54 Jump Game
- [leetcode 54] Spiral Matrix
- [LeetCode 54]Spiral Matrix
- Spiral Matrix - LeetCode 54
- leetcode 54 : Spiral Matrix
- Leetcode #54 Spiral Matrix
- leetcode 54: Jump Game
- leetCode(54):Gas Station
- Leetcode#54||Spiral Matrix
- LeetCode (54) Valid Anagram
- leetcode 54:Jump Game
- 【leetcode】【54】Spiral Matrix
- LeetCode 54 - Spiral Matrix
- 【LeetCode-54】Spiral Matrix
- LeetCode 54 Spiral Matrix
- android 获得一个应用程序的启动次数,运行时间等信息
- IOS 7 SDK Multitasking 多任务
- myeclipse开发基于cxf的webservice
- QMYSQL3: Unable to bind value
- android调试的必杀技——反汇编
- LeetCode(54) SpiralMatrix
- 算法入门经典 7.4.4 带宽问题 回溯 剪枝
- 九度OJ 1499 项目安排 -- 动态规划
- QT中三种数据类型之间的转换:
- Python中一些内置函数
- 有一段文本,将文本中的所有单词存放到一个字符串数组中
- <context-param>与<init-param>的区别与作用
- class.getResource()的用法
- 资料