题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入: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]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof
知识点:
- 对于考察矩阵的题目前我们学习到了三个,分别是66.机器人的运动范围与1.二维数组中的查找
- 这三道题中,机器人的运动范围用到了递归,其他均是for循环便好,而机器人的运动范围与这道题均需要通过对象key的唯一性来判断当前元素是否遍历过
- 对于这三道题我们要掌握其基本的思路,与大概的步骤是怎样的便可以写出来
解题思路:
- 这道题给我们一个矩阵,要求我将矩阵从外到里顺时针打印(实际上我们是从外向里逆时针将矩阵中的元素放入数组中)
- 对于遍历矩阵的题我们首先要创建一个对象用于判断该元素是否走过
- 其次我们需要创建两个变量记录矩阵的行与列数
- 最后,也是这道题精妙的地方,我们会创建一个数组来控制遍历矩阵时的方向
- 在for循环中其退出的条件为所有的格子已经走完,注意这里一定是step<m * n不能等于
- 之后就是将符合条件的行与列放入数组中,将其标记为走过,然后再走下一步,然后再判断是否符合条件…..
解题代码:
var spiralOrder = function(matrix) {
if(!matrix.length || !matrix[0].length) return [];
// 1.创建两个变量记录行和列的长度
let m = matrix.length;
let n = matrix[0].length;
// 2.创建一个对象记录走过的位置
let visited = {};
// 3.创建一个数组记录结果
let res = [];
// 4.创建一个数组用于后续改变方向
let direction = [
[0,1],
[1,0],
[0,-1],
[-1,0]
]
// 5.创建一个方法用于生成对象的key
function setKey(i,j){
return `[${i},${j}]`
}
// 对于确定走的路径的二维数组我们使用循环便可
// 注意:这里step的判断条件不能等于
for(let row = 0,col = 0,dIndex = 0,step = 0;step < m*n;step++) {
// 6.将走过的路径记录并放入res中
res.push(matrix[row][col]);
visited[setKey(row,col)] = true;
// 7.继续走向下一个元素
let newRow = row + direction[dIndex][0];
let newCol = col + direction[dIndex][1];
let tempKey = setKey(newRow,newCol);
if(newRow >= 0 && newCol >= 0 && newRow < m && newCol < n && !visited[tempKey]) {
row = newRow;
col = newCol;
}else {
// 改变方向
dIndex = (dIndex + 1) % 4;
row = row + direction[dIndex][0];
col = col + direction[dIndex][1];
}
}
return res;
};