力扣刷题——3244. 新增道路查询后的最短距离 II

是思路题,其实能想到的话是很简单的。首先,用3243的图遍历搜索方法肯定是会超时的,然后注意到用例跟3243不一样的是,询问集合里没有交集,那么就可以定下一个策略"在有捷径就走捷径的情况下,答案是最优的",这个策略在该题里是正确的。
因此可以通过计算捷径覆盖的区域,然后用n-1减去这个区域的长度即可得到答案,有一个简单的实现:

vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) 
{
    vector<int> res;
    vector<int> uni(n);
    int temRes = n - 1;
    for(int i = 0; i < queries.size(); i++)
    {
        for(int j = queries[i][0] + 1; j < queries[i][1]; j++)
        {
            if(uni[j] == 0)                
            {
                temRes--;
                uni[j] = 1;
            }
        }
        res.emplace_back(temRes);
    }
    return res;
}

然而这个实现是会超时的,问题出在计算捷径覆盖区域的时候引入了很多重复计算,比如[0,28],[0,30],更好的做法是,保存先前区域的左侧连接到的位置,在这个基础上去计算覆盖的区域大小,这样实现:

vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries)
{
    vector<int> res;
    vector<int> nex(n - 1);
    for(int i = 0; i < nex.size(); i++)
    {
        nex[i] = i + 1;            
    }
    int temRes = n - 1;
    for(int i = 0; i < queries.size(); i++)
    {
        int left = queries[i][0], right = queries[i][1];
        if(nex[left] && nex[left] < right)
        {
            for(int j = nex[left]; j < right;)
            {
                temRes--;
                int tem = nex[j];
                nex[j] = 0;
                j = tem;
            }
            nex[left] = right;
        }
        res.emplace_back(temRes);
    }
    return res;
}
posted @ 2024-11-20 10:00  SuzumiyaYui  阅读(7)  评论(0)    收藏  举报