字节&剑指 Offer 29:顺时针打印矩阵(螺旋矩阵)
sisterAn opened this issue · comments
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 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
用四个变量up, down, left, right分别记录当前上下左右范围,每遍历一行或一列就修改相应的值。
例如遍历了上面第一行,就应该把up加一,遍历了右边第一列就应把right减一
var spiralOrder = function(matrix) {
if (matrix === undefined || matrix.length === 0) return [];
let res = [];
let left = 0, right = matrix[0].length-1, up = 0, down = matrix.length-1;
while (true) {
for (let i = left;i <= right;i++) {
res.push(matrix[up][i]);
}
if (++up > down) break;
for (let i = up;i <= down;i++) {
res.push(matrix[i][right]);
}
if (--right < left) break;
for (let i = right;i >= left;i--) {
res.push(matrix[down][i]);
}
if (--down < up) break;
for (let i = down;i >= up;i--) {
res.push(matrix[i][left]);
}
if (++left > right) break;
}
return res;
};
核心是四种情况的判断:
- 向右移动(没到右边界一直右移动遍历),到达右边界就向下移动(如果向下也是边界,说明遍历完了)
- 向下移动(没到下边界一直下移动遍历),到达下边界就向左移动(如果向左也是边界,说明遍历完了)
- 向左移动(没到左边界一直左移动遍历),到达左边界就向上移动(如果向上也是边界,说明遍历完了)
- 向上移动(没到上边界一直上移动遍历),到达上边界就向右移动(如果向右也是边界,说明遍历完了)
var PrintMatrixClockwise = function (matrix) {
let border = { // 存储边界
top: 0,
left: 0,
bottom: matrix.length - 1,
right: matrix[0].length - 1
}
let direction = 'right' // top、right、bottom、left
let result = []
let location = [0, 0] // 当前坐标
function forword() { // 向前移动
switch (direction) {
case 'top':
if (location[1] >= border['top']) {
// 继续向前走
result.push(matrix[location[1]][location[0]])
location[1]--
} else if (location[0] + 1 <= border['right']) {
// 此方向到头了,向右
location[0]++
location[1]++
direction = 'right'
border['left']++
} else return
break;
case 'right':
if (location[0] <= border['right']) {
// 继续向前走
result.push(matrix[location[1]][location[0]])
location[0]++
} else if (location[1] + 1 <= border['bottom']) {
// 此方向到头了,向下
location[0]--
location[1]++
direction = 'bottom'
border['top']++
} else return
break;
case 'bottom':
if (location[1] <= border['bottom']) {
// 继续向前走
result.push(matrix[location[1]][location[0]])
location[1]++
} else if (location[0] - 1 >= border['left']) {
// 此方向到头了,向左
location[0]--
location[1]--
direction = 'left'
border['right']--
} else return
break;
case 'left':
if (location[0] >= border['left']) {
// 继续向前走
result.push(matrix[location[1]][location[0]])
location[0]--
} else if (location[1] - 1 >= border['top']) {
// 此方向到头了,向上
location[0]++
location[1]--
direction = 'top'
border['bottom']--
} else return
break;
}
// 递归
forword()
}
forword()
return result
}
一圈一圈删除
function fn(arr) {
const res = []
while (arr.length) {
res.push(...arr.shift())
if (arr.length) {
const last = arr.pop()
if (arr.length) {
arr.forEach(val => {
res.push(val.pop())
})
}
res.push(...last.reverse())
if (arr.length) {
const temp = []
arr.forEach(val => {
temp.push(val.shift())
})
res.push(...temp.reverse())
}
}
}
return res
}
function echoValueClockWise(matrix) {
const temp = matrix.slice();
const result = [];
while (temp.length > 0) {
result.push(...temp.shift());
temp.forEach(arr => result.push(arr.pop()));
result.push(...(temp.pop() || []).reverse());
for (let i = temp.length - 1; i > -1; i--) {
result.push(temp[i].shift());
}
}
return result;
}
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
if(matrix.length===0) {
return []
}
const res = [];
//1. 定义左边界 右边界 上边界 下边界
let m = matrix.length;
let n = matrix[0].length;
let l = 0, r = n - 1, t = 0, b = m - 1;
let matrixSize = m * n;
while (res.length < matrixSize) {
for (let i = l; i <= r; i++) {
res.push(matrix[t][i]);
}
t++;
for (let i = t; i <= b; i++) {
res.push(matrix[i][r]);
}
r--;
if(res.length === matrixSize) {
break;
}
for (let i = r; i >= l; i--) {
res.push(matrix[b][i]);
}
b--;
for (let i = b; i >= t; i--) {
res.push(matrix[i][l]);
}
l++;
}
return res;
};
var matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
var queryFn = function (matrix) {
if(matrix.length===0) return []
let res = []
let left = 0,
right = matrix[0].length-1,
top = 0,
bottom = matrix.length-1
let n = matrix[0].length * matrix.length
while(true) {
if(left>right) break
for(let i = left; i <= right; i++) {
res.push(matrix[top][i])
}
top++
if(top>bottom) break
for(let i=top; i <= bottom; i++) {
res.push(matrix[i][right])
}
right--
if(left>right) break
for(let i=right; i >= left; i--) {
res.push(matrix[bottom][i])
}
bottom--
if(top>bottom) break
for(let i=bottom; i >= top; i--) {
res.push(matrix[i][left])
}
left++
}
return res
}
queryFn(matrix)
// [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]