剑指Offer 29 - 顺时针打印矩阵
Posted xintangchn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指Offer 29 - 顺时针打印矩阵相关的知识,希望对你有一定的参考价值。
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
思路一:顺时针旋转路径
从左上角出发,初始方向向右,当超出边界或进入之前访问过的区域时,顺时针旋转方向。
要点:
- 判断某位置是否已访问过:用一个布尔数组记录,访问过的位置标记为1
- 顺时针方向旋转的实现:
用一个二维数组directions表示前进方向:{{0,1}, {1,0}, {0,-1}, {-1, 0}}
索引0-3表示:向右(行数不变,列数加一),向下(列数加一,行数不变),向左(行数不变,列数减一),向上(列数减一,行数不变)
向右走一步: row += directions[0][0],col += directions[0][1], 以此类推
顺时针旋转,即前进方向改为下一个索引,越界则循环:directionIndex = (1 + directionIndex) % 4
代码:
var spiralOrder = function(matrix) { if(matrix == null || matrix.length === 0) return []; const rows = matrix.length, cols= matrix[0].length; const total = rows * cols; let visited = new Array(); for(let i = 0; i < rows; i++){ visited[i] = new Array(); for(let j = 0; j < cols; j++){ visited[i][j] = 0; } } let res = []; const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; let directionIndex = 0; let i = 0, j = 0; for(let n = 0; n < total; n++){ res[n] = matrix[i][j]; visited[i][j] = 1; let nextRow = i + directions[directionIndex][0]; let nextCol = j + directions[directionIndex][1]; if(nextRow >= rows || nextRow < 0 || nextCol >= cols || nextCol < 0 || visited[nextRow][nextCol]){ directionIndex = (directionIndex + 1) % 4; } i = i + directions[directionIndex][0]; j = j + directions[directionIndex][1]; } return res; };
易错点:
- visited数组需要初始化
- 数组越界注意上下界都要判断
- corner case:矩阵为空
思路二: 一层一层打印
用 left, right, top, buttom 标记当前打印的层数的边界,最后一行/一列单独打印。
代码:
var spiralOrder = function(matrix) { if(matrix == null || matrix.length === 0) return []; let rows = matrix.length, cols = matrix[0].length; let left = 0, right = cols - 1, top = 0, buttom = rows - 1; let res = []; while(left < right && top < buttom){ //上 for(let j = left; j < right; j++){ res.push(matrix[top][j]); } //右 for(let i = top; i < buttom; i++){ res.push(matrix[i][right]); } //下 for(let j = right; j > left; j--){ res.push(matrix[buttom][j]); } //左 for(let i = buttom; i > top; i--){ res.push(matrix[i][left]); } left++; right--; top++; buttom--; } //最后一列 if(left === right){ for(let i = top; i <= buttom; i++){ res.push(matrix[i][left]) } } //最后一行 else if(top === buttom){ for(let j = left; j <= right; j++){ res.push(matrix[top][j]); } } return res; };
以上是关于剑指Offer 29 - 顺时针打印矩阵的主要内容,如果未能解决你的问题,请参考以下文章