“Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。”
一、题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 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]
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
二、思路分析:
解题思路并不难,模拟遍历的过程。难点在于模拟过程中对于边界的判断。
使用let top=0,bottom=m-1,left=0,right=n-1,表示遍历的上下左右边界,ans=[]表示最后遍历的结果。i,j表示位于矩阵的行和列
顺序遍历为从i=top开始j++一直遍历到right,即遍历到底,同时遍历到边界后,top++缩短方位,开始i=top,j=right向下遍历j–直到到达下底bottom,right遍历完元素right–。
此时应该开始向左遍历,但要考虑一个特殊情况,当matricx只有一行时,因为是以j=right,i=bottom开始j–,就会重复遍历!所以要判断top<=bottom?为true才能执行。同理对于只有一列的数组,执行从下到上时也要判断left<=right?为true才能继续遍历。
当一轮遍历完时,原数组就减少了最外面的一层。那么什么时候才能结束遍历?因为当left与right重合时,代表的含义是这行或列还没遍历,故等于的情况还需要继续遍历,直到left>right,对top和bottom同理
三、AC 代码:
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
if(!matrix.length||!matrix[0].length)return []
let m=matrix.length,n=matrix[0].length
let top=0,bottom=m-1,left=0,right=n-1,ans=[]
while(top<=bottom&&left<=right){
for(let j=left;j<=right;j++){
ans.push(matrix[top][j])
}
top++;
for(let i=top; i<=bottom;i++){
ans.push(matrix[i][right])
}
right--
for(let j=right; j>=left&&top<=bottom;j--){
ans.push(matrix[bottom][j])
}
bottom--
for(let i=bottom;i>=top&&left<=right;i--){
ans.push(matrix[i][left])
}
left++
}
return ans
};
复制代码
四、总结:
本题思路不复杂,就是进行模拟。但是对边界的判断很繁琐,要是选择的遍历方式不是一下到底就可能要进行繁琐的加减操作得到想要的位置。以及本题对结束循环的条件的思索也很有意思,通过减少范围判断是否该结束循环