54. 螺旋矩阵(JavaScript)

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

示例 2:

输入:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

思路:

方法一:

设置一个标志矩阵,大小与原矩阵相同,初始时的元素均为1,代表相同位置上的原矩阵元素未被访问,0代表已被访问。

设置方向变量direction,0、1、2、3分别代表右、下、左、上四个方向。

设置结果数组result = [ ].

遍历标志矩阵:当前tag位存在且为1时,将此元素加入结果数组,并将tag为置为0,并判断此时的方向:

1、方向为0(右),若右边的元素不存在,或已被访问,则改变方向为1(下),否则继续向右移动一格

2、方向为1(下),若下边的元素不存在,或已被访问,则改变方向为2(左),否则继续向下移动

3、方向为2(左),若左边的元素不存在,或已被访问,则改变方向为3(上),否则继续向左移动

4、方向为3(上),若上边的元素不存在,或已被访问,则改变方向为0(右),否则继续向上移动

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
  if (matrix.length === 0) return []
  let tag = [],
      row = matrix.length,
      col = matrix[0].length,
      direction = 0,  // 0右,1下,2左,3上
      result = []
  for (let i = 0; i < row; i++) {
    tag[i] = [];
    for (let j = 0; j < col; j++) {
      tag[i][j] = 1;  // 1:未访问,0:已访问
    }
  }
  let r = 0,
      c = 0;
  while(tag[r] && tag[r][c] === 1) {
    result.push(matrix[r][c])
    tag[r][c] = 0
    switch(direction) {
      case 0:
        if (!tag[r][c+1]) {
          direction = 1
          r++
        } else { c++ }
        break
      case 1:
        if (tag[r+1] && tag[r+1][c]) {
          r++
        } else {
          direction = 2
          c--
        }
        break
      case 2:
        if (!tag[r][c-1]) {
          direction = 3
          r--
        } else { c-- }
        break
      case 3:
        if (!tag[r-1][c]) {
          direction = 0
          c++
        } else { r-- }
        break
    }
  }
  return result;
};

方法二:

设置四个端点——上下左右:top、bottom、left、right

当上小于等于下、左小于等于右时循环:

1、向右移动,从left到right这一行元素加入结果数组result,之后将top++,(因为最上面一行都计入了,所以top要加1)并判断此时top与bottom是否合理

2、向下移动,从top到bottom这一列元素加入result,之后将right--,并判断right是否大于l等于eft

3、向左移动,加入从right到left这一行元素,之后将bottom--,同样判断bottom是否还大于等于top

4、向上移动,加入从bottom到top这一列元素,之后将left++,同样判断left是否还小于等于right

循环中任何时候只要top大于了bottom或者left大于了right,就要跳出循环。

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
  if (matrix.length === 0) return []
  let top = 0,
      bottom = matrix.length - 1,
      left = 0,
      right = matrix[0].length - 1,
      result = [];
  while (top <= bottom && left <= right) {
    for (let j = left; j <= right; j ++) {
      result.push(matrix[top][j])
    }
    if (++top > bottom) break
    for (let i = top; i <= bottom; i++) {
      result.push(matrix[i][right])
    }
    if (--right < left) break
    for (let j = right; j >= left; j--) {
      result.push(matrix[bottom][j])
    }
    if (--bottom < top) break
    for (let i = bottom; i >= top; i--) {
      result.push(matrix[i][left])
    }
    if (++left > right) break
  }
  return result
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的桐人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值