You are given an integer n and a 2D integer array queries.
There are n cities numbered from 0 to n - 1. Initially, there is a unidirectional road from city i to city i + 1 for all 0 <= i < n - 1.
queries[i] = [uᵢ, vᵢ] represents the addition of a new unidirectional road from city uᵢ to city vᵢ. After each query, you need to find the length of the shortest path from city 0 to city n - 1.
There are no two queries such that queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1].
Return an array answer where for each i in the range [0, queries.length - 1], answer[i] is the length of the shortest path from city 0 to city n - 1 after processing the firsti + 1 queries.
因为道路不会交叉,设有一条道路 [u, v],那么城市 u 和 v 之间的城市(即 [u+1, u+2, ..., v-2, v-1])就都可以忽略掉(因为对于任何 u < i < v,从城市 i 出发,不可能一步走到 v 之后)。所有的道路都加好之后,剩下的城市就是从 0 走到 n-1 的必经点,剩余城市个数减去一就是距离。
记录从城市 i 出发,一步可以走到的最远的城市为 f[i]。初始时 f[i] = i + 1。
初始的时候,集合中有所有城市。增加一条道路 [u, v] 时,如果 u 已经不在集合中或者 v <= f[u],则这条道路对于缩短距离没有帮助,直接忽略。否则就把集合中所有 u < i < v 的城市 i 都删掉。删的时候不需要遍历 u 到 v 的所有值,因为现在集合中只有 f[u], f[f[u]], ..., f[...f[u]] < v,依次删掉这些即可。
把 f[u] 从集合中删掉,并继续看 f[f[u]],直到走到 v 就停止,然后将 f[u] 的值更新为 v。
classSolution:defshortestDistanceAfterQueries(self,n:int,queries:list[list[int]])->list[int]:f=[i+1foriinrange(n)]# f[i] == n means i was removed.dis=n-1results=[dis]*len(queries)forq,(u,v)inenumerate(queries):if(i:=f[u])<v:f[u]=vwhilei<v:f[i],i=n,f[i]dis-=1# City `i` removed.results[q]=disreturnresults
评论需要 JavaScript。