Skip to content

Commit 25abc21

Browse files
author
robot
committed
feat: Connected-Road-to-Destination
1 parent 7cfbcc6 commit 25abc21

File tree

3 files changed

+170
-3
lines changed

3 files changed

+170
-3
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ https://github.com/fe-lucifer/fanqiang
5454
![](https://tva1.sinaimg.cn/large/008i3skNly1gq0mm4lscqj313h0r0diy.jpg)
5555

5656
- [第四期即将开始报名](https://leetcode-solution.cn/91) 🔥🔥🔥🔥
57-
- [第一期讲义-二分法](./91/binary-search.md)
58-
- [第一期讲义-双指针](./91/two-pointers.md)
57+
- [91 第三期讲义 - 二分专题(上)](./thinkings/binary-search-1.md)
58+
- [91 第三期讲义 - 二分专题(下)](./thinkings/binary-search-2.md)
59+
- [91 第一期讲义 - 双指针](./91/two-pointers.md)
5960

6061
## 刷题群
6162

@@ -427,7 +428,8 @@ leetcode 题解,记录自己的 leetcode 解题之路。
427428
- [Kth Pair Distance](./problems/Kth-Pair-Distance.md) 91
428429
- [Minimum Light Radius](./problems/Minimum-Light-Radius.md) 91
429430
- [Largest Equivalent Set of Pairs](./problems/Largest-Equivalent-Set-of-Pairs.md) 👍
430-
- [Ticket-Order.md](./problemsTicket-Order.md)
431+
- [Ticket-Order.md](./problems/Ticket-Order.md)
432+
- [Connected-Road-to-Destination](./problems/Connected-Road-to-Destination.md)
431433

432434
- [0004. 寻找两个正序数组的中位数](./problems/4.median-of-two-sorted-arrays.md) 👍
433435
- [0023. 合并 K 个升序链表](./problems/23.merge-k-sorted-lists.md)

SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@
262262
- [Kth-Pair-Distance](./problems/Kth-Pair-Distance.md) 91
263263
- [Minimum-Light-Radius](./problems/Minimum-Light-Radius.md) 91
264264
- [Largest Equivalent Set of Pairs](./problems/Largest-Equivalent-Set-of-Pairs.md) 🆕 👍
265+
- [Ticket-Order.md](./problems/Ticket-Order.md)
266+
- [Connected-Road-to-Destination](./problems/Connected-Road-to-Destination.md)
265267
- [0004. 寻找两个正序数组的中位数](./problems/4.median-of-two-sorted-arrays.md)
266268
- [0023. 合并 K 个升序链表](./problems/23.merge-k-sorted-lists.md)
267269
- [0025. K 个一组翻转链表](./problems/25.reverse-nodes-in-k-groups.md)
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
## 题目地址
2+
3+
https://binarysearch.com/problems/Connected-Road-to-Destination
4+
5+
## 题目描述
6+
7+
```
8+
You are given integers sx, sy, ex, ey and two-dimensional list of integers roads. You are currently located at coordinate (sx, sy) and want to move to destination (ex, ey). Each element in roads contains (x, y) which is a road that will be added at that coordinate. Roads are added one by one in order. You can only move to adjacent (up, down, left, right) coordinates if there is a road in that coordinate or if it's the destination coordinate. For example, at (x, y) we can move to (x + 1, y) if (x + 1, y) is a road or the destination.
9+
10+
Return the minimum number of roads in order that must be added before there is a path consisting of roads that allows us to get to (ex, ey) from (sx, sy). If there is no solution, return -1.
11+
12+
Constraints
13+
14+
0 ≤ n ≤ 100,000 where n is the length of roads
15+
Example 1
16+
Input
17+
sx = 0
18+
sy = 0
19+
ex = 1
20+
ey = 2
21+
roads = [
22+
[9, 9],
23+
[0, 1],
24+
[0, 2],
25+
[0, 3],
26+
[3, 3]
27+
]
28+
Output
29+
3
30+
Explanation
31+
We need to add the first three roads which allows us to go from (0, 0), (0, 1), (0, 2), (1, 2). Note that we must take (9, 9) since roads must be added in order.
32+
33+
34+
```
35+
36+
## 前置知识
37+
38+
- 二分
39+
- 并查集
40+
41+
## 二分(超时)
42+
43+
本质就是能力检测二分。关于能力检测二分,我在我的[二分专题](https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-search-2.md)已经做了详细的介绍,不再赘述。
44+
45+
因为我们我们只需要在 [0, len(roads)] 值域内做能力检测即可,然后根据检测结果二分值域。由于是求**最小**的满足起点和终点联通的铺设道路的数量,因此使用最左二分即可。
46+
47+
这里我套用了最左二分的模板。 问题的关键是能力检测如何写?**这里的能力检测本质是检测在给的前 x 个 roads,问起点和终点是否联通**
48+
49+
不妨使用 BFS, 从 起点开始搜索,如果存在一条通路到终点,那么返回存在即可。要搜索就需要构建图,构图的关键是构建边。这道题的边其实就是**点的上下左右邻居**,不过**邻居要在 roads 中存在才行哦**,这点需要注意。据此,不难写出如下代码。
50+
51+
### 思路
52+
53+
### 代码
54+
55+
```py
56+
class Solution:
57+
def solve(self, sx, sy, ex, ey, roads):
58+
def possible(mid):
59+
dic = set([(sx, sy), (ex, ey)])
60+
visited = set()
61+
q = collections.deque([(sx, sy)])
62+
for x, y in roads[:mid]:
63+
dic.add((x, y))
64+
while q:
65+
x, y = q.popleft()
66+
if (x, y) in visited: continue
67+
visited.add((x, y))
68+
if (x, y) == (ex, ey): return True
69+
for dx, dy in [(1,0),(-1,0), (0,1), (0,-1)]:
70+
if (x + dx, y + dy) in dic:
71+
q.append((x + dx, y + dy))
72+
return False
73+
l, r = 0, len(roads)
74+
75+
while l <= r:
76+
mid = (l + r) // 2
77+
if possible(mid):
78+
r = mid - 1
79+
else:
80+
l = mid + 1
81+
return -1 if l > len(roads) else l
82+
```
83+
84+
**复杂度分析**
85+
86+
令 n 为 roads 的长度。
87+
88+
- 时间复杂度:$O(nlogn)$,logn 用于二分,n 用于能力检测。
89+
- 空间复杂度:$O(n)$
90+
91+
## 并查集
92+
93+
### 思路
94+
95+
上面我不停地提起**联通** 这个词。这提示我们使用并查集来完成。
96+
97+
从起点不断**加边**,直到起点和终点联通或者 roads 加入完了。同样,可以使用我的[并查集专题](https://github.com/azl397985856/leetcode/blob/master/thinkings/union-find.md)的模板。
98+
99+
由于需要**加边**,因此对模板需要进行一点小小调整,增加 add(x) api 用于**加点**,功能是将 x 加入到图中,接下来使用 union **加边**即可。
100+
101+
### 代码
102+
103+
代码支持:Python3
104+
105+
Python Code:
106+
107+
```py
108+
109+
class UF:
110+
def __init__(self):
111+
self.parent = {}
112+
self.cnt = 0
113+
def add(self, i):
114+
self.parent[i] = i
115+
self.cnt += 1
116+
117+
def find(self, x):
118+
if x != self.parent[x]:
119+
self.parent[x] = self.find(self.parent[x])
120+
return self.parent[x]
121+
return x
122+
def union(self, p, q):
123+
if p not in self.parent or q not in self.parent: return
124+
if self.connected(p, q): return
125+
leader_p = self.find(p)
126+
leader_q = self.find(q)
127+
self.parent[leader_p] = leader_q
128+
self.cnt -= 1
129+
def connected(self, p, q):
130+
return self.find(p) == self.find(q)
131+
132+
class Solution:
133+
def solve(self, sx, sy, ex, ey, roads):
134+
start = (sx, sy)
135+
end = (ex, ey)
136+
# 注意特判
137+
for dx, dy in [(0, 0), (1,0), (-1,0), (0,1), (0,-1)]:
138+
x = sx + dx
139+
y = sy + dy
140+
if (x, y) == (ex, ey): return 0
141+
142+
uf = UF()
143+
uf.add(start)
144+
uf.add(end)
145+
146+
for i, road in enumerate(map(tuple, roads)):
147+
uf.add(road)
148+
for dx, dy in [(1,0), (-1,0), (0,1), (0,-1)]:
149+
x = road[0] + dx
150+
y = road[1] + dy
151+
uf.union(road, (x, y))
152+
if uf.connected(start, end):
153+
return i + 1
154+
155+
return -1
156+
```
157+
158+
**复杂度分析**
159+
160+
令 n 为 roads 的长度。
161+
162+
- 时间复杂度:$O(n)$
163+
- 空间复杂度:$O(n)$

0 commit comments

Comments
 (0)