day14 题目:剑指 Offer 12. 矩阵中的路径剑指 Offer 13. 机器人的运动范围

知识点:数组、回溯、搜索,难度为中等、中等

学习计划链接:「剑指 Offer」 - 学习计划

题目知识点难度
剑指 Offer 12. 矩阵中的路径数组回溯矩阵中等
剑指 Offer 13. 机器人的运动范围深度优先搜索广度优先搜索中等

# 剑指 Offer 12. 矩阵中的路径

给定一个  m x n  二维字符网格  board  和一个字符串单词  word  。如果  word  存在于网格中,返回  true  ;否则,返回  false  。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中 “相邻” 单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

示例 1:

输入: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出: true

示例 2:

输入: board = [["a","b"],["c","d"]], word = "abcd"
输出: false

提示:

  • 1 <= board.length <= 200
  • 1 <= board[i].length <= 200
  • board  和  word  仅由大小写英文字母组成

注意: 本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/

# 思路

非常典型的深搜典型题,以矩阵中每个符合单词开头的元素作为起点开始搜。

/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function(board, word) {
    function dfs(i, j, idx) {
        if(idx == word.length) return true // 找到单词了
        if(i < 0 || i >= board.length || j < 0 || j >= board[0].length 
            || board[i][j] == '#' || board[i][j] != word[idx]) 
            return false // 越界或者不匹配
        board[i][j] = '#'   // 置为 #,避免重复访问
        let flag = false
        if(dfs(i+1, j, idx+1) || dfs(i-1, j, idx+1) 
        || dfs(i, j+1, idx+1) || dfs(i, j-1, idx+1))    // 四个方向试探
            flag = true
        board[i][j] = word[idx] // 恢复
        return flag
    }
    for(let i = 0; i < board.length; ++i) {
        for(let j = 0; j < board[0].length; ++j) {
            if(board[i][j] === word[0])
                if(dfs(i, j, 0)) return true
        }
    }
    return false
};

# 剑指 Offer 13. 机器人的运动范围

地上有一个 m 行 n 列的方格,从坐标  [0,0]  到坐标  [m-1,n-1]  。一个机器人从坐标  [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于 k 的格子。例如,当 k 为 18 时,机器人能够进入方格 [35, 37] ,因为 3+5+3+7=18。但它不能进入方格 [35, 38],因为 3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入: m = 2, n = 3, k = 1
输出: 3

示例 2:

输入: m = 3, n = 1, k = 0
输出: 1

提示:

  • 1 <= n,m <= 100
  • 0 <= k <= 20

# 思路

广搜,注意搜索方向可以向右和向下就行了

/**
 * @param {number} m
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
var movingCount = function(m, n, k) {
    function count(x) {
        if(x == 0) return 0
        let sum = 0
        while(x) {
            sum += x%10
            x = Math.floor(x/10)
        }
        return sum
    }
  
    let dx = [1, 0]
    let dy = [0, 1]  // 下 右
    let canVis = new Array(m).fill(0).map(() => new Array(n).fill(false))
    let vis = new Array(m).fill(0).map(() => new Array(n).fill(false))
    for(let i = 0; i < m; ++i)
        for(let j = 0; j < n; ++j)
            canVis[i][j] = (count(i) + count(j)) <= k
    function judge(i, j) {
        if(i < 0 || i >= m || j < 0 || j >= n || !canVis[i][j] || vis[i][j])
            return false
        return true
    }
    let q = []
    let ans = 0
    vis[0][0] = true
    q.push([0, 0])
    while(q.length) {
        let [x, y] = q.shift()
        ++ans
        for(let i = 0; i < 2; ++i) {
            let nx = x + dx[i]
            let ny = y + dy[i]
            if(judge(nx, ny)) {
                vis[nx][ny] = true
                q.push([nx, ny])
            }
        }
    }
    return ans
};
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

cos 微信支付

微信支付

cos 支付宝

支付宝