[leecode 剑指offer] 顺时针打印矩阵
题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
思路:
按层模拟
可以将矩阵看成若干层,首先打印最外层的元素,其次打印次外层的元素,直到打印最内层的元素。
定义矩阵的第 k 层是到最近边界距离为 kk 的所有顶点。例如,下图矩阵最外层元素都是第 1层,次外层元素都是第 2 层,剩下的元素都是第 3 层。
[[1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 1],
[1, 2, 3, 3, 3, 2,1],
[1, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 1, 1]]
对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于 (top,left),右下角位于 (bottom,right),按照如下顺序遍历当前层的元素。
从左到右遍历上侧元素,依次为(top,left) 到(top,right)。
从上到下遍历右侧元素,依次为 (top+1,right) 到 (bottom,right)。
如果left<right 且 top<bottom,则从右到左遍历下侧元素,依次为 (bottom,right?1) 到 (bottom,left+1),以及从下到上遍历左侧元素,依次为(bottom,left) 到 (top+1,left)。
遍历完当前层的元素之后,将 left 和 top 分别增加 11,将 right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止。
算法思路
算法实现
var spiralOrder = function(matrix) {
if(matrix.length==0){
//当二维数组为空时返回空数组return new Array();}//每层四个顶角位置var top = 0,bottom = matrix.length-1,left = 0,right=matrix[0].length-1;//保存遍历结果var res = new Array();while(top<=bottom&&left<=right){
//按层顺时针遍历for(let i=left;i<=right;i++){
res.push(matrix[top][i]);}//自左向右for( let i = top+1;i<=bottom;i++){
res.push(matrix[i][right]);}//自右上向右下if(top<bottom&&left<right){
//当此层遍历不为单行或者单列时for(let i=right-1;i>=left;i--){
res.push(matrix[bottom][i]);}//自右下向左下for(let i=bottom-1;i>top;i--){
res.push(matrix[i][left]);}//自左下向左上}//遍历下一层left++;right--;top++;bottom--;}return res;
};
总结
这个算法不算难,重点在于怎么分析题目,并将自己的想法通过代码的形式解决。本体最大的难点在于找到按层遍历的临界值,找到临界值便能顺利完成这到题。