前端算法面试必刷题系列[20]

239 阅读2分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

34. 螺旋矩阵 (spiral-matrix)

标签

  • 二维数组
  • 中等

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

例:

image.png

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

基本思路

算出一共多少个元素(row * columns),然后一圈一圈地遍历矩阵,停止条件就是遍历了所有元素(count == sum) 如图是四个角坐标

(top, left)       (top, right)
        

(bottom, left)    (bottom, right)

然后我们一圈圈遍历也简单,分这四步,把四边顺时针输出就行

  • (top, left) => (top, right)
  • (top + 1, right) => (bottom, right)
  • (bottom, right - 1) => (bottom, left)
  • (bottom - 1, left) => (top + 1, left)

写法实现

var spiralOrder = function(matrix) {
  let res = []
  let [rows, columns] = [matrix.length, matrix[0].length]
  // top、left、right、bottom 分别是剩余区域的上、左、右、下的下标
  let [left, right, top, bottom] = [0, columns - 1, 0, rows - 1]
  // 当前数组长度和长度总和,用来做边界条件的, i, j 是循环的临时变量
  let [count, sum, i, j] = [0, rows * columns, 0, 0]

  // 从左上角开始,一层一层遍历, 每次遍历一圈
  while(count < sum) {
    // 这是上面一横条 (top, left)=> (top, right)
    [i, j] = [top, left]
    while (j <= right && count < sum) {
      res.push(matrix[i][j])
      count++
      j++
    }
    // 这是右边竖条 (top + 1, right)=> (bottom, right)
    [i, j] = [top + 1, right]
    while (i <= bottom && count < sum) {
      res.push(matrix[i][j])
      count++
      i++
    }
    // 下面横条往左边走向 (bottom, right - 1) => (bottom, left)
    [i, j] = [bottom, right - 1]
    while (j >= left && count < sum) {
      res.push(matrix[i][j])
      count++
      j--
    }
    // 再往上数走到顶 (bottom - 1, left) => (top + 1, left)
    [i, j] = [bottom - 1, left]
    while (i > top && count < sum) {
      res.push(matrix[i][j])
      count++
      i--
    }
    // 一圈结束开始进入下一圈
    [top, left, bottom, right] = [top+1, left+1, bottom-1, right-1]
  }
  return res
};

let matrix = [[1,2,3],[4,5,6],[7,8,9]]

console.log(spiralOrder(matrix))

35. 跳跃游戏 (jump-game)

标签

  • 文字理解
  • 中等

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定一个非负整数数组,最初位于数组的第一个位置。数组中的每个元素代表在该位置可以跳跃的最大长度。判断是否能够到达最后一个位置

基本思路

  1. 如果某一个作为 起跳点 的格子可以跳跃的距离是 n,那么表示后面 n 个格子都可以作为 起跳点。
  2. 可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离maxJump 不断更新。
  3. 如果可以一直跳到最后,就成功了。如果中间有一个点比 maxJump 还要大,说明在这个点和 maxJump 中间连不上了。

写法实现

var canJump = function(nums) {
  let len = nums.length
  if (len === 1) {
    return true
  }
  let curJumpMaxLen = 0
  for (let i = 0; i < len; i++) {
    if (i > curJumpMaxLen) {
      return false
    }
    curJumpMaxLen = Math.max(curJumpMaxLen, i + nums[i])
  }
  return true
};

let nums = [3,2,1,0,4]

console.log(canJump(nums))

另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考