0
点赞
收藏
分享

微信扫一扫

神经网络有哪些算法

目录


0.原理讲解

  • 注意:只要是用**BFS解决的最短路径问题,都要求边权为一(边权值相同)**

  • 单源最短路径

    • 把起点加入到队列中
    • 一层一层的往外扩展
  • 多源BFS:用BFS解决边权为一多源最短路径问题
    请添加图片描述

  • 法一:暴力解,把多源最短路径问题转化为若干个单源最短路问题

    • 效率低,大概率会超时
  • 法二:把所有的源点当成一个"超级源点"

    • 此时问题就变成了「单源最短路径」问题
      请添加图片描述
  • "超级源点"的正确性?感性理解

    • 同时从几个源点出发,会存在"舍弃"几个"不好的点"的现象
    • 远的源点走一步肯定没有近的源点走一步好,所以相当于舍去了远的源点
  • 多源BFS如何代码实现?

    • 所有的源点加入到队列里面
    • 一层一层的往外扩展
      请添加图片描述

1.矩阵

1.题目链接

  • 矩阵

2.算法原理详解

  • 思路一:一个位置一个位置求

    • 不用想,这么暴力肯定超时:P
  • 思路二多源BFS + 正难则反 -> 把所有的0当成起点,1当成终点

    • 把所有的0位置加入到队列中
    • 一层一层的向外拓展即可
      请添加图片描述
  • 为什么正着做会很困难呢?

    • 正着做虽然能找到0,但是想把距离存下来,会很难
    • 并且也无法知道是哪个1到了0,距离是多少
  • 为什么本题用到了多源BFS呢?

    • 0是有很多个的,怎么才能保证遇到的1距离这⼀个0是最近的?
    • 先把所有的0都放在队列中,把它们当成⼀个整体,每次把当前队列⾥⾯的所有元素向外扩展⼀次
  • 细节:在单源最短路径中需要:bool visit[i][j]stepsz,而在多源BFS中,只需要一个int dist[i][j]就可以替代这三者的功能

    • 为什么可以替代bool visit[i][j]
      • dist[][]初始化为-1-1表示没有搜索过
      • dist[i][j] != -1则为最短距离
    • <为什么可以替代step
      • (a, b) -> (x, y)dist[a][b]存储了dist[x][y]上一步的距离
        • dist[x][y] = dist[a][b] + 1
    • 为什么可以替代sz
      • 因为不强制一定要按层一层一层出队列,可以一个元素一个元素的往外扩展
      • 不需要知道此时是哪一层,dist[i][j]已经标记了现在是属于哪一层

3.代码实现

vector<vector<int>> UpdateMatrix(vector<vector<int>>& mat) 
{
    int n = mat.size(), m = mat[0].size();

    // dist[i][j] == -1 未搜索过
    // dist[i][j] != -1 最短距离
    vector<vector<int>> dist(n, vector<int>(m, -1));
    queue<pair<int, int>> q;

    // 将所有源点加入到队列中
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(mat[i][j] == 0)
            {
                q.push({i, j});
                dist[i][j] = 0;
            }
        }
    }

    // 多源BFS
    while(q.size())
    {
        auto [a, b] = q.front();
        q.pop();

        // 将下一层入队列
        for(int i = 0; i < 4; i++)
        {
            int x = a + dx[i], y = b + dy[i];

            if(x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
            {
                dist[x][y] = dist[a][b] + 1;
                q.push({x, y});
            }
        }
    }

    return dist;
}

2.飞地的数量

1.题目链接

  • 飞地的数量

2.算法原理详解

  • 思路一:一个一个去判断
    • 不用想,这么暴力肯定超时:P
  • 思路二多源BFS + 正难则反 -> 从边界上的1开始,做一次搜索
    • 多源BFS结束后,重新遍历一次数组,最后剩下来的就都是飞地
      请添加图片描述

3.代码实现

int NumEnclaves(vector<vector<int>>& grid) 
{
    int n = grid.size(), m = grid[0].size();
    vector<vector<bool>> visit(n, vector<bool>(m, false));
    queue<pair<int, int>> q;

    // 将所有边界1入队列
    for(int i = 0; i < n; i++)
    {
        if(grid[i][0] == 1)
        {
            q.push({i, 0});
            visit[i][0] = true;
        }

        if(grid[i][m - 1] == 1)
        {
            q.push({i, m - 1});
            visit[i][m - 1] = true;
        }
    }

    for(int i = 0; i < m; i++)
    {
        if(grid[0][i] == 1)
        {
            q.push({0, i});
            visit[0][i] = true;
        }

        if(grid[n - 1][i] == 1)
        {
            q.push({n - 1, i});
            visit[n - 1][i] = true;
        }
    }

    // 多源BFS
    while(q.size())
    {
        auto [a, b] = q.front();
        q.pop();

        // 下一层入队列
        for(int i = 0; i < 4; i++)
        {
            int x = a + dx[i], y = b + dy[i];

            if(x >= 0 && x < n && y >= 0 && y < m \
               && grid[x][y] == 1 && !visit[x][y])
            {
                visit[x][y] = true;
                q.push({x, y});
            }
        }
    }

    // 遍历计数
    int count = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(grid[i][j] == 1 && !visit[i][j])
            {
                count++;
            }
        }
    }

    return count;
}

3.地图中的最高点

1.题目链接

  • 地图中的最高点

2.算法原理详解

  • "01矩阵"变形题,直接多源BFS即可

3.代码实现

class Solution 
{
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    vector<vector<int>> highestPeak(vector<vector<int>>& isWater) 
    {
        int n = isWater.size(), m = isWater[0].size();
        vector<vector<int>> dist(n, vector<int>(m, -1));
        queue<pair<int, int>> q;
        
        // 将边界水域入队列
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                if(isWater[i][j])
                {
                    dist[i][j] = 0;
                    q.push({i, j});
                }
            }
        }

        // 多源BFS
        while(q.size())
        {
            auto [a, b] = q.front();
            q.pop();

            // 下一层入队列
            for(int i = 0; i < 4; i++)
            {
                int x = a + dx[i], y = b + dy[i];

                if(x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
                {
                    dist[x][y] = dist[a][b] + 1;
                    q.push({x, y});
                }
            }
        }

        return dist;
    }
};

4.地图分析

1.题目链接

  • 地图分析

2.算法原理详解

  • "01矩阵"变形题,直接多源BFS即可

3.代码实现

class Solution 
{
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    int maxDistance(vector<vector<int>>& grid) 
    {
        int n = grid.size();
        vector<vector<int>> dist(n, vector(n, -1));
        queue<pair<int, int>> q;

        // 将陆地入队列
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j])
                {
                    dist[i][j] = 0;
                    q.push({i, j});
                }
            }
        }

        // 多源BFS
        int ret = -1;
        while(q.size())
        {
            auto [a, b] = q.front();
            q.pop();

            // 下层入队列
            for(int i = 0; i < 4; i++)
            {
                int x = a + dx[i], y = b + dy[i];

                if(x >= 0 && x < n && y >= 0 && y < n && dist[x][y] == -1)
                {
                    dist[x][y] = dist[a][b] + 1;
                    q.push({x, y});
                    ret = max(ret, dist[x][y]);
                }
            }
        }

        return ret;
    }
};
举报

相关推荐

0 条评论