1
+ class Solution {
2
+ /*
3
+ We use bits to store the keys found till now. We can move to each cell multiple times, with different number of keys available
4
+ to us at a particular time. Therefore time complexity - O(mn*2^k) as 2^k is the no. of states possible. K is no. of keys represented
5
+ as bits can be 0/1.
6
+ if we find a key and we want to add that information to already found key.
7
+ keys = keys | (1 << (c - 'a'))
8
+
9
+ To check if a key is present
10
+ (keys >> c-'a')&1 == 1
11
+
12
+ To check if keys collected till now is all those are present.
13
+ convert decimal representation 'k' to binary by (1 << k) - 1 and compare with keys.
14
+ */
15
+ int [][] dirs = new int [][]{{1 ,0 }, {0 ,-1 }, {-1 ,0 }, {0 ,1 }};
16
+ public int shortestPathAllKeys (String [] grid ){
17
+ int m = grid .length ;
18
+ int n = grid [0 ].length ();
19
+ int startX = -1 ;
20
+ int startY = -1 ;
21
+ int k = 0 ;
22
+ for (int i =0 ; i <m ; i ++){
23
+ for (int j =0 ; j <n ; j ++) {
24
+ char c = grid [i ].charAt (j );
25
+ if (c == '@' ) {
26
+ startX = i ;
27
+ startY = j ;
28
+ }
29
+ if (isKey (c )) {
30
+ k ++;
31
+ }
32
+ }
33
+ }
34
+ System .out .println (" key " + k );
35
+ Node start = new Node (startX , startY , 0 );
36
+ Queue <Node > q = new LinkedList <>();
37
+ q .offer (start );
38
+ Set <String > visited = new HashSet <>();
39
+ visited .add (startX + " " + startY + " " + 0 );
40
+ int level = 0 ;
41
+ while (!q .isEmpty ()) {
42
+ int size = q .size ();
43
+ for (int i =0 ; i <size ; i ++) {
44
+ Node cur = q .poll ();
45
+ int res = (1 << k ) - 1 ;
46
+ //System.out.println(res);
47
+ if (cur .keys == (1 << k ) - 1 ) { // for 2 total keys, (1 << 2) - 1 = 4 -1 = 3.
48
+ return level ;
49
+ }
50
+ for (int [] d : dirs ) {
51
+ int x = cur .i + d [0 ];
52
+ int y = cur .j + d [1 ];
53
+ int keys = cur .keys ;
54
+
55
+ if (!isValid (grid , x , y , m , n )) {
56
+ continue ;
57
+ }
58
+ char c = grid [x ].charAt (y );
59
+ if (isKey (c )) {
60
+ keys = keys | (1 << (c - 'a' )); // for 2 keys, it will look like 11 which is equal to 3.
61
+ }
62
+ if (isLock (c ) && (keys >> (c - 'A' ) & 1 ) == 0 ) {
63
+ continue ;
64
+ }
65
+ if (visited .add (x + " " + y + " " + keys )) {
66
+ q .offer (new Node (x , y , keys ));
67
+ }
68
+ }
69
+ }
70
+ level ++;
71
+ }
72
+ return -1 ;
73
+ }
74
+
75
+ public boolean isLock (char c ) {
76
+ return c >= 'A' && c <= 'F' ;
77
+ }
78
+
79
+ public boolean isKey (char c ) {
80
+ return c >= 'a' && c <= 'f' ;
81
+ }
82
+
83
+ public boolean isValid (String [] grid , int i , int j , int m , int n ) {
84
+ return i >= 0 && i < m && j >= 0 && j < n && grid [i ].charAt (j ) != '#' ;
85
+ }
86
+
87
+ class Node {
88
+ int i , j , keys ;
89
+ public Node (int i , int j , int keys ) {
90
+ this .i = i ;
91
+ this .j = j ;
92
+ this .keys = keys ;
93
+ }
94
+ }
95
+ }
0 commit comments