1
- class Solution :
2
- def shortestPathLength (self , graph : List [List [int ]]) -> int :
3
- n = len (graph )
4
- fullmask = (1 << n ) - 1
5
- used = [set () for i in range (n )]
6
- q = deque ()
7
- state = 1
8
- for i in range (n ):
9
- q .append ([i , state ])
10
- used [i ].add (state )
11
- state <<= 1
12
- d = - 1
13
- while q :
14
- d += 1
15
- for _ in range (len (q )):
16
- v , mask = q .popleft ()
17
- if mask == fullmask :
18
- return d
19
- for u in graph [v ]:
20
- newMask = mask | (1 << u )
21
- if newMask not in used [u ]:
22
- q .append ([u , newMask ])
23
- used [u ].add (newMask )
24
- return 0
1
+ class Node (object ):
2
+ def __init__ (self , nodeId , visitedSoFar ):
3
+ self .id = nodeId
4
+ self .journal = visitedSoFar
5
+
6
+ def __eq__ (self , other ):
7
+ return self .id == other .id and self .journal == other .journal
8
+
9
+ def __repr__ (self ):
10
+ return "Node({}, {})" .format (self .id , bin (self .journal )[2 :])
11
+
12
+ def __hash__ (self ):
13
+ return hash ((self .id , self .journal ))
14
+
15
+
16
+ class Solution (object ):
17
+ def shortestPathLength (self , graph ):
18
+ """
19
+ :type graph: List[List[int]]
20
+ :rtype: int
21
+ """
22
+ N = len (graph )
23
+ # 1<<i represents nodes visitedSoFar to reach this node
24
+ # when initializing, we don't know the best node to start
25
+ # our journey around the world with. So we add all
26
+ # nodes to our queue aka travel journal !
27
+ q = collections .deque (Node (i , 1 << i ) for i in range (N ))
28
+ distanceToThisNode = collections .defaultdict (lambda :N * N )
29
+ for i in range (N ):
30
+ distanceToThisNode [Node (i , 1 << i )] = 0
31
+
32
+ endJournal = (1 << N ) - 1
33
+ # when we have visited all nodes, this is how our journal
34
+ # aka visitedSoFar at that node would look like.
35
+
36
+ while (q ):
37
+ node = q .popleft ()
38
+
39
+ dist = distanceToThisNode [node ]
40
+
41
+ if (node .journal == endJournal ):
42
+ return dist
43
+
44
+ neighbouring_cities = graph [node .id ]
45
+
46
+ for city in neighbouring_cities :
47
+ newJournal = node .journal | (1 << city )
48
+ # doing an OR operation with 1<<city essentially adds
49
+ # this city to the journal. aka sets that nodeId to 1
50
+
51
+ neighbour_node = Node (city , newJournal )
52
+
53
+ if dist + 1 < distanceToThisNode [neighbour_node ]:
54
+ distanceToThisNode [neighbour_node ] = dist + 1
55
+ q .append (neighbour_node )
56
+ return - 1
57
+
58
+
0 commit comments