为什么类似的网格左上角走到右下角的题目,一个BFS超时,一个BFS不超时

来源:9-2 第一个动态规划问题 Climbing Stairs

慕斯卡8072790

2021-11-20

题目一:
使用BFS超时的题目

// LeetCode 64号问题,超时代码
// 我的第一思路就是BFS搜索求最短路径,然后就超时了
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class Solution {
private:
    int R, C;
    int dirs[2][2] = {{1, 0}, {0, 1}};

    struct node
    {
        int x, y, s;

        bool operator<(const node o) const {
            return s > o.s;
        }
    }cur, nextN;

    bool inArea(int x, int y) {
        return x >= 0 && x < R && y >= 0 && y < C;
    }

public:
    int minPathSum(vector<vector<int>>& grid) {
        R = grid.size();
        C = grid[0].size();
        priority_queue<node> que;
        que.push({0, 0, grid[0][0]});
        if( 0 == R-1 && 0 == C-1 ) {
            return grid[0][0];
        }
        while( !que.empty() ) {  // 尝试自己分析复杂度,觉得最差情况每次push两倍节点,所以是O(2^n)复杂度
            cur = que.top();
            que.pop();
            for( int d = 0 ; d < 2 ; d++ ) {
                int nextx = cur.x + dirs[d][0];
                int nexty = cur.y + dirs[d][1];
                if( inArea(nextx, nexty) ) {
                    nextN.x = nextx;
                    nextN.y = nexty;
                    nextN.s = grid[nextx][nexty] + cur.s;
                    que.push(nextN);
                    if( nextx == R-1 && nexty == C-1 )
                        return nextN.s;
                }
            }
        }
        return -1;
    }
};

int main()
{
    vector<vector<int>> vec = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
    cout<<Solution().minPathSum(vec)<<endl;
    return 0;
}

题目二:
使用BFS不超时的题目为什么这类似的题目又不超时了?

写回答

2回答

liuyubobobo

2021-11-20

你的第一个代码的时间复杂度不是 V + E 的。bfs 里记录了 ( 顶点 + 当前访问这个顶点的时候对应的 cost)两个信息,所以,bfs 访问的状态数是 (顶点总数 * cost 的可能性) 这么多。也就是每个顶点在不同的 cost 下是会不断访问的。你可以在循环里不断地打印一下你的 queue 的 size,看看是不是在呈指数级的上升。


这里的关键是,bfs 处理的是无权图的最短路径问题,而第一个问题是一个带权图。如果你用最短路径的思路做,应该用 dijkstra。而由于这个问题限制了每一步只能向右或者向下走,所以存在最优子结构,可以使用 dp。


继续加油!:) 

1
1
慕斯卡8072790
理解了,谢谢。
2021-11-20
共1条回复

慕斯卡8072790

提问者

2021-11-20

突然想起,BFS的时间复杂度是O(V+E),而dp的复杂度是O(V),这两个复杂度的差距应该只是 BFS的系数大一些呀,也不至于TLE溢出吧。

0
0

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7410 学习 · 1150 问题

查看课程