-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNo752OpenTheLock.java
More file actions
111 lines (97 loc) · 2.6 KB
/
No752OpenTheLock.java
File metadata and controls
111 lines (97 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package com.wzx.leetcode;
import java.util.*;
/**
* @see <a href="https://leetcode.com/problems/open-the-lock/">https://leetcode.com/problems/open-the-lock/</a>
* @author wzx
*/
public class No752OpenTheLock {
/**
* 单向广搜
* <p>
* time: O(n)
* space: O(n)
*/
public int openLock1(String[] deadends, String target) {
Deque<String> queue = new LinkedList<>();
// 起点
queue.addLast("0000");
Set<String> visit = new HashSet<>(Arrays.asList(deadends));
int step = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String wheels = queue.pollFirst();
// 找到目标
if (target.equals(wheels)) {
return step;
}
if (!visit.contains(wheels)) {
visit.add(wheels);
for (int j = 0; j < 4; j++) {
queue.addLast(rollUp(wheels, j));
queue.addLast(rollDown(wheels, j));
}
}
}
step++;
}
return -1;
}
private String rollUp(String wheels, int index) {
char[] chars = wheels.toCharArray();
if (chars[index] == '9') {
chars[index] = '0';
} else {
chars[index]++;
}
return new String(chars);
}
private String rollDown(String wheels, int index) {
char[] chars = wheels.toCharArray();
if (chars[index] == '0') {
chars[index] = '9';
} else {
chars[index]--;
}
return new String(chars);
}
/**
* 在知道终点的情况下,可以双向广搜,使用hashset替换队列,便于两个搜索方向的比较
* <p>
* time: O(n)
* space: O(n)
*/
public int openLock2(String[] deadends, String target) {
// 正向搜索
Set<String> set1 = new HashSet<>();
set1.add("0000");
// 反向搜索
Set<String> set2 = new HashSet<>();
set2.add(target);
Set<String> visit = new HashSet<>(Arrays.asList(deadends));
int step = 0;
while (!set1.isEmpty() && !set2.isEmpty()) {
// 优先扩大搜索方向元素较少的,便于快速找到target
if (set1.size() > set2.size()) {
Set<String> tmp = set1;
set1 = set2;
set2 = tmp;
}
// set1的下一个搜索空间
Set<String> nextSet = new HashSet<>();
for (String wheels : set1) {
if (set2.contains(wheels)) return step;
if (!visit.contains(wheels)) {
visit.add(wheels);
for (int i = 0; i < 4; i++) {
nextSet.add(rollUp(wheels, i));
nextSet.add(rollDown(wheels, i));
}
}
}
set1 = nextSet;
step++;
}
return -1;
}
}