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