【leetcode】2101.引爆最多的炸弹

118 阅读2分钟

leetcode-2101.png

题目简述:有若干个炸弹,给出炸弹的坐标(x,y)以及爆炸半径r,若一个炸弹在另外一个炸弹的爆炸半径r之内的时候,就会引爆它,求引爆一个炸弹的前提下,最多可以引爆多少个炸弹。

这是一题图论题目,用邻接表来解答,每个邻接表里面放着与之能引爆的邻接炸弹,然后使用dfs或者bfs来求解

DFS

var maximumDetonation = function (bombs) {
    let len = bombs.length
    let graph = Array.from({ length: len }, () => [])
    // 构建邻接表
    for (let i = 0; i < len; ++i) {
        for (let j = 0; j < len; ++j) {
            let [x1, y1, r1] = bombs[i]
            let [x2, y2, r2] = bombs[j]
            let dist = (x2 - x1) ** 2 + (y2 - y1) ** 2
            // j 在 i的爆炸半径之内,则放入邻接表
            if (dist <= r1 ** 2) {
                graph[i].push(j)
            }
        }
    }
    // dfs 来进行遍历
    var dfs = function (i, visited) {
        visited[i] = true
        let count = 1
        // 从当前引爆的炸弹的邻接表中来进行遍历
        for (let n of graph[i]) {
            // 没有引爆过的,则进行引爆,然后进行计数
            if (!visited[n]) {
                // 引爆邻接的炸弹
                count += dfs(n, visited)
            }
        }
        return count
    }
    let maxBombs = 0
    // 遍历每一个炸弹(从每个炸弹都开始,计算每一种情况
    for (let i = 0; i < len; ++i) {
        // 对于每一次迭代的 i 而言,都是一次全行的爆炸之旅
        // 所以要重新初始化 visited 数组
        let visited = Array(len).fill(false)
        maxBombs = Math.max(maxBombs, dfs(i, visited))
    }
    return maxBombs
};

BFS

var maximumDetonation = function (bombs) {
    let len = bombs.length
    let graph = Array.from({ length: len }, () => [])
    // 构建邻接表
    for (let i = 0; i < len; ++i) {
        for (let j = 0; j < len; ++j) {
            let [x1, y1, r1] = bombs[i]
            let [x2, y2, r2] = bombs[j]
            let dist = (x2 - x1) ** 2 + (y2 - y1) ** 2
            // j 在 i的爆炸半径之内,则放入邻接表
            if (dist <= r1 ** 2) {
                graph[i].push(j)
            }
        }
    }
    // bfs 来进行遍历
    var bfs = function (i) {
        // 记录是否被引爆
        let visited = Array(len).fill(false)
        visited[i] = true
        let queue = [i]
        let count = 0
        while (queue.length) {
            // 取出最前面的节点
            let node = queue.shift()
            // 队列有多大,就能引爆多少个,所以在这里 计数
            count++
            // 找到邻接炸弹
            for (let n of graph[node]) {
                // 没有引爆过的邻接炸弹,放入队列之中等待引爆
                if (!visited[n]) {
                    visited[n] = true
                    queue.push(n)
                }
            }
        }
        return count
    }
    let maxBombs = 0
    // 遍历每一个炸弹(从每个炸弹都开始,计算每一种情况
    for (let i = 0; i < len; ++i) {
        maxBombs = Math.max(maxBombs, bfs(i))
    }
    return maxBombs
};