-
Notifications
You must be signed in to change notification settings - Fork 2
/
OpenTheLock.java
108 lines (99 loc) · 3.63 KB
/
OpenTheLock.java
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
package queue.bfs;
import java.util.*;
/**
* 752. Open the Lock
* 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.
*
* The lock initially starts at '0000', a string representing the state of the 4 wheels.
*
* 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.
*
* 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.
*
*
*
* Example 1:
*
* Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
* Output: 6
* Explanation:
* A sequence of valid moves would be "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202".
* Note that a sequence like "0000" -> "0001" -> "0002" -> "0102" -> "0202" would be invalid,
* because the wheels of the lock become stuck after the display becomes the dead end "0102".
*
* IMP-1: Excellent question to practice BFS based search to target.
*/
public class OpenTheLock {
private Set<String> visited = new HashSet<>();
public static void main(String[] args) {
String[] strDeadEnds = {"8887", "8889", "8878", "8898", "8788", "8988", "7888", "9888"};
OpenTheLock openTheLock = new OpenTheLock();
int numMoves = openTheLock.openLock(strDeadEnds, "8888");
System.out.println(numMoves);
}
public int openLock(String[] deadends, String target) {
String start = "0000";
Queue<String> queue = new LinkedList<>();
String level = "L";
queue.add(start);
queue.add(level);
Set<String> deads = new HashSet<>();
Collections.addAll(deads, deadends);
int passes = 0;
while (!queue.isEmpty()) {
String str = queue.poll();
if (str.equals(level)) {
passes++;
if (!queue.isEmpty()) {
queue.add(level);
}
continue;
}
if (str.equals(target)) {
return passes;
}
if (deads.contains(str)) {
continue;
}
List<String> possibleTransforms = transform(str);
queue.addAll(possibleTransforms);
}
return -1;
}
List<String> transform(String str) {
List<String> strTransforms = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
char val = str.charAt(i);
String strNewA = str.substring(0, i) + transformCharAhead(val) + str.substring(i + 1);
String strNewB = str.substring(0, i) + transformCharBack(val) + str.substring(i + 1);
if (!visited.contains(strNewA)) {
strTransforms.add(strNewA);
visited.add(strNewA);
}
if (!visited.contains(strNewB)) {
strTransforms.add(strNewB);
visited.add(strNewB);
}
}
return strTransforms;
}
String transformCharAhead(char givenChar) {
int i = givenChar - 48;
int iNext = i + 1;
iNext = iNext % 10;
return String.valueOf(iNext);
}
String transformCharBack(char givenChar) {
int i = givenChar - 48;
int iNext = i - 1;
if (iNext == -1) {
iNext = 9;
}
return String.valueOf(iNext);
}
}