剑指-JS-03

103 阅读4分钟

1. 机器人的运动范围

DFS
var movingCount = function (m, n, k) {
  const visited = Array.from(Array(m), () => Array(n).fill(false))
  // 计算x和y坐标的值
  function sum (num) {
    let ans = 0
    while (num) {
      ans += num % 10
      num = Math.floor(num / 10)
    }
    return ans
  }
  function dns (x, y) {
    // 如果超出边界或者访问过就返回0
    if (x >= m || y >= n || sum(x) + sum(y) > k || visited[x][y]) {
      return 0
    }
    // 进入格子 标记访问过
    visited[x][y] = true
    return dns(x + 1, y) + dns(x, y + 1) + 1
  }
  return dns(0, 0)
}
// console.log(movingCount(5, 4, 3))

// BFS
var movingCount = function (m, n, k) {
  const arr = Array.from(Array(m), () => Array(n).fill(0))
  // 创建一个队列 从(0,0)开始搜索
  const queue = [[0, 0]]
  // 计数器
  let counter = 0
  function sum (num) {
    let ans = 0
    while (num) {
      ans += num % 10
      num = Math.floor(num / 10)
    }
    return ans
  }
  while (queue.length) {
    const [x, y] = queue.shift()
    if (x >= m || y >= n) continue
    if (arr[x][y] === 1) continue
    arr[x][y] = 1
    console.log(arr);
    if (sum(x) + sum(y) <= k) {
      counter++
      queue.push([x + 1, y], [x, y + 1])
    }
  }
  return counter
}

2. 剪绳子

// 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?
// 例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

// 示例 1:

// 输入: 2
// 输出: 1
// 解释: 2 = 1 + 1, 1 × 1 = 1
// 示例 2:

// 输入: 10
// 输出: 36
// 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
var cuttingRope = function(n){
    if(n==2) return 1
    if(n==3) return 2
    let p = 1
    while(n>4){
        p*=3
        n-=3
    }
    p*=n

}

console.log(cuttingRope(7));

3. 树的子结构

// 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

// B是A的子结构, 即 A中有出现和B相同的结构和节点值。

// 例如:
// 给定的树 A:

//      3
//     / \
//    4   5
//   / \
//  1   2
// 给定的树 B:

//    4 
//   /
//  1
// 返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

// 示例 1:

// 输入:A = [1,2,3], B = [3,1]
// 输出:false

// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

var isSubStructure = function(A,B){
    // AB为空返回false
    if(A===null||B===null) return false
    // 以AB为根节点
    const dfs = (A,B)=>{
        if(B===null) return true
        if(A===null) return false
        if(A.val === B.val) return dfs(A.left,B.left) && dfs(A.right,B.right)
        else return false
    }
    return dfs(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B)
}

4. 二叉树的镜像

// 请完成一个函数,输入一个二叉树,该函数输出它的镜像。

// 例如输入:

//      4
//    /   \
//   2     7
//  / \   / \
// 1   3 6   9
// 镜像输出:

//      4
//    /   \
//   7     2
//  / \   / \
// 9   6 3   1

//

// 示例 1:

// 输入:root = [4,2,7,1,3,6,9]
// 输出:[4,7,2,9,6,3,1]

// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

var mirrorTree = function (root) {
  if (root) {
    [root.left, root.right] = [root.right, root.left]
    mirrorTree(root.left)
    mirrorTree(root.right)
  }
}

5. 对称二叉树

// 请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

// 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

//     1
//    / \
//   2   2
//  / \ / \
// 3  4 4  3
// 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

//     1
//    / \
//   2   2
//    \   \
//    3    3

//

// 示例 1:

// 输入:root = [1,2,2,3,4,4,3]
// 输出:true
// 示例 2:

// 输入:root = [1,2,2,null,3,null,3]
// 输出:false

// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

var isSymmetric = function (root) {
  if (root == null) return true
  return dfs(root.left, root.right)
  function dfs (left, right) {
    if (left === null && right === null) return true
    if (left == null || right == null || left.val != right.val) return false
    return dfs(left.left, right.right) && dfs(left.right, right.left)
  }
}

6. 顺时针打印矩阵

// 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

//

// 示例 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
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
// var spiralOrder = function (matrix) {
//   let dx = [0, 1, 0, -1]
//   let dy = [1, 0, -1, 0]

//   // 总共需要打印的数字
//   let count = matrix.length * matrix[0].length
//   let ans = []
//   let x = 0,
//     y = 0
//   let direct = 0
//   let deleted = -101
//   while (ans.length < count) {
//     ans.push(matrix[x][y])
//     matrix[x][y] = deleted
//     if (
//       x + dx[direct] < 0 ||
//       x + dx[direct] >= matrix.length ||
//       y + dy[direct] < 0 ||
//       y + dy[direct] >= matrix[x].length ||
//       matrix[x + dx[direct]][y + dy[direct]] == deleted
//     ) {
//       direct = (direct + 1) % 4
//     }
//     x = x + dx[direct]
//     y = y + dy[direct]
//   }
//   console.log(ans)
//   return ans
// }

var spiralOrder = function (matrix) {
  // 定方向
  let dx = [0, 1, 0, -1]
  let dy = [1, 0, -1, 0]
  // 步数
  let count = matrix.length * matrix[0].length
  let ans = []
  let x = 0,
    y = 0
  let direct = 0
  let deleted = -111
  while (ans.length < count) {
    ans.push(matrix[x][y])
    matrix[x][y] = -111
    // 下一步 四个方向循环
    if (
      x + dx[direct] < 0 ||
      y + dy[direct] < 0 ||
      x + dx[direct] >= matrix.length ||
      y + dy[direct] >= matrix.length ||
      matrix[x + dx[direct]][y + dy[direct]] == deleted
    ) {
      direct = (direct + 1) % 4
    }
    x = x + dx[direct]
    y = y + dy[direct]
  }
  console.log(ans)
  return ans
}

spiralOrder([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
])

7. 包含min函数的栈

// 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

// 示例:

// MinStack minStack = new MinStack();
// minStack.push(-2);
// minStack.push(0);
// minStack.push(-3);
// minStack.min();   --> 返回 -3.
// minStack.pop();
// minStack.top();      --> 返回 0.
// minStack.min();   --> 返回 -2.
//

// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class MinStack {
  constructor () {
    this.stackA = []
    this.countA = 0
    this.stackB = []
    this.countB = 0
  }

  push (item) {
    this.stackA[this.countA++] = item
    if (this.countB == 0 || item < this.min()) {
      this.stackB[this.countB++] = item
    }
  }
  min () {
    return this.stackB[this.countB - 1]
  }
  top () {
    return this.stackA[this.countA - 1]
  }
  pop () {
    if (this.top() <= this.min()) {
      delete this.stackB[--this.countB]
    }
    delete this.stackA[--this.countA]
  }
}