Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc2a74a9

Browse files
committed
752-open-the-lock.md Added Python solution in 2 ways.
1 parentb43e110 commitc2a74a9

File tree

2 files changed

+475
-0
lines changed

2 files changed

+475
-0
lines changed

‎en/1-1000/752-open-the-lock.md

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#752. Open the Lock - Best Practices of LeetCode Solutions
2+
LeetCode link:[752. Open the Lock](https://leetcode.com/problems/open-the-lock), difficulty:**Medium**.
3+
4+
##LeetCode description of "752. Open the Lock"
5+
You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots:`'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'`. The wheels can rotate freely and wrap around: for example we can turn`9` to be`0`, or`0` to be`9`. Each move consists of turning one wheel one slot.
6+
7+
The lock initially starts at`0000`, a string representing the state of the 4 wheels.
8+
9+
You are given a list of`deadends` dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.
10+
11+
Given a`target` representing the value of the wheels that will unlock the lock, return_the**minimum total number** of turns required to open the lock, or`-1` if it is impossible_.
12+
13+
###[Example 1]
14+
**Input**:`deadends = ["0201","0101","0102","1212","2002"], target = "0202"`
15+
16+
**Output**:`6`
17+
18+
**Explanation**:
19+
```
20+
A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
21+
Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid,
22+
because the wheels of the lock become stuck after the display becomes the dead end "0102".
23+
```
24+
25+
###[Example 2]
26+
**Input**:`deadends = ["8888"], target = "0009"`
27+
28+
**Output**:`1`
29+
30+
**Explanation**:
31+
```
32+
We can turn the last wheel in reverse to move from "0000" -> "0009".
33+
```
34+
35+
###[Example 3]
36+
**Input**:`["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"`
37+
38+
**Output**:`-1`
39+
40+
**Explanation**:`We cannot reach the target without getting stuck.`
41+
42+
###[Constraints]
43+
-`1 <= deadends.length <= 500`
44+
-`deadends[i].length == 4`
45+
-`target.length == 4`
46+
-`target`**will not be** in the list`deadends`.
47+
-`target` and`deadends[i]` consist of digits only.
48+
49+
###[Hints]
50+
<details>
51+
<summary>Hint 1</summary>
52+
We can think of this problem as a shortest path problem on a graph: there are`10000` nodes (strings`'0000'` to`'9999'`), and there is an edge between two nodes if they differ in one digit, that digit differs by 1 (wrapping around, so`'0'` and`'9'` differ by 1), and if*both* nodes are not in`deadends`.
53+
</details>
54+
55+
##Intuition
56+
We can think of this problem as a shortest path problem on a graph: there are`10000` nodes (strings`'0000'` to`'9999'`), and there is an edge between two nodes if they differ in one digit, that digit differs by 1 (wrapping around, so`'0'` and`'9'` differ by 1), and if*both* nodes are not in`deadends`.
57+
58+
###Solution 1: Breadth-First Search
59+
![](../../images/binary_tree_BFS_1.gif)
60+
61+
* As shown in the figure above,**Breadth-First Search** can be thought of as visiting vertices in rounds and rounds. Actually, whenever you see a question is about
62+
getting`minimum number` of something of a graph,`Breadth-First Search` would probably help.
63+
64+
*`Breadth-First Search` emphasizes first-in-first-out, so a**queue** is needed.
65+
66+
###Solution 2: A* (A-Star) Algorithm
67+
68+
**A-Star Algorithm** can be used to improve the performance of**Breadth-First Search Algorithm**.
69+
70+
**Breadth-First Search** treats each vertex equally, which inevitably leads to poor performance.
71+
72+
**A-Star Algorithm** calculates the**distance** between each`vertex` and the`target vertex`, and prioritizes vertices with close distances, which greatly improves performance.
73+
74+
####A* (A-Star) Algorithm Has Two (or Three) Key Actions
75+
1. Use`priority_queue`.
76+
2. The function for calculating`distance` should be**carefully designed** (poor design will lead to**subtle** errors in the results).
77+
3. In special cases, simply using`distance` as the sorting basis for`priority_queue` is not enough, and you need to**make some adjustments**, such as adding it to the`step_count` variable value (not involved in this example).
78+
79+
##Complexity
80+
>`N` is the length of`deadends`.
81+
82+
###Solution 1: Breadth-First Search
83+
* Time:`O(10^4)`.
84+
* Space:`O(N)`.
85+
86+
###Solution 2: A* (A-Star) Algorithm
87+
* Time:`O(5 * 4 * 4 * 2 + N)`.
88+
* Space:`O(N)`.
89+
90+
##Python
91+
###Solution 1: Breadth-First Search
92+
```python
93+
classSolution:
94+
defopenLock(self,deadends: List[str],target_digits:str) ->int:
95+
if'0000'== target_digits:
96+
return0
97+
98+
self.deadends=set(deadends)
99+
if'0000'in deadends:
100+
return-1
101+
102+
self.queue= deque(['0000'])
103+
self.deadends.add('0000')
104+
self.target_digits= target_digits
105+
result=0
106+
107+
whileself.queue:
108+
result+=1
109+
queue_size=len(self.queue)
110+
111+
for _inrange(queue_size):
112+
digits=self.queue.popleft()
113+
114+
ifself.turn_one_slot(digits):
115+
return result
116+
117+
return-1
118+
119+
defturn_one_slot(self,digits):
120+
for iinrange(len(digits)):
121+
for digitin closest_digits(int(digits[i])):
122+
new_digits=f'{digits[:i]}{digit}{digits[i+1:]}'
123+
124+
if new_digits==self.target_digits:
125+
returnTrue
126+
127+
if new_digitsinself.deadends:
128+
continue
129+
130+
self.queue.append(new_digits)
131+
self.deadends.add(new_digits)
132+
133+
134+
defclosest_digits(digit):
135+
if digit==0:
136+
return (9,1)
137+
138+
if digit==9:
139+
return (8,0)
140+
141+
return (digit-1, digit+1)
142+
```
143+
144+
###Solution 2: A* (A-Star) Algorithm
145+
```python
146+
classSolution:
147+
defopenLock(self,deadends: List[str],target_digits:str) ->int:
148+
if'0000'== target_digits:
149+
return0
150+
151+
deadends=set(deadends)
152+
if'0000'in deadends:
153+
return-1
154+
155+
self.target_digits= target_digits
156+
157+
priority_queue= [(self.distance('0000'),'0000',0)]
158+
159+
while priority_queue:
160+
_, digits, turns= heapq.heappop(priority_queue)
161+
162+
for iinrange(4):
163+
for digitin closest_digits(int(digits[i])):
164+
new_digits=f'{digits[:i]}{digit}{digits[i+1:]}'
165+
166+
if new_digits== target_digits:
167+
return turns+1
168+
169+
if new_digitsin deadends:
170+
continue
171+
172+
heapq.heappush(
173+
priority_queue,
174+
(self.distance(new_digits), new_digits, turns+1)
175+
)
176+
deadends.add(new_digits)
177+
178+
return-1
179+
180+
defdistance(self,digits):
181+
result=0
182+
183+
# 0 1 2 3 4 5 6 7 8 9
184+
# 0 1 2 3 4 5 6 7 8 9
185+
# 0 1 2 3 4 5 6 7 8 9
186+
# 0 1 2 3 4 5 6 7 8 9
187+
for iinrange(4):
188+
# 'Euclidean Distance' is widely used in 'A* Algorithm'.
189+
result+=abs(int(self.target_digits[i])-int(digits[i]))**2
190+
191+
return result**0.5
192+
193+
194+
defclosest_digits(digit):
195+
if digit==0:
196+
return (9,1)
197+
198+
if digit==9:
199+
return (8,0)
200+
201+
return (digit-1, digit+1)
202+
```
203+
204+
##JavaScript
205+
```javascript
206+
// Welcome to create a PR to complete the code of this language, thanks!
207+
```
208+
209+
##Java
210+
```java
211+
// Welcome to create a PR to complete the code of this language, thanks!
212+
```
213+
214+
##C++
215+
```cpp
216+
// Welcome to create a PR to complete the code of this language, thanks!
217+
```
218+
219+
##C#
220+
```c#
221+
// Welcome to create a PR to complete the code of this language, thanks!
222+
```
223+
224+
##Go
225+
```go
226+
// Welcome to create a PR to complete the code of this language, thanks!
227+
```
228+
229+
##Ruby
230+
```ruby
231+
# Welcome to create a PR to complete the code of this language, thanks!
232+
```
233+
234+
##C, Kotlin, Swift, Rust or other languages
235+
```
236+
// Welcome to create a PR to complete the code of this language, thanks!
237+
```

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp