forked from PriyankaKhire/ProgrammingPracticePython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAirbnb Interview Digraph.py
More file actions
145 lines (123 loc) · 4.17 KB
/
Airbnb Interview Digraph.py
File metadata and controls
145 lines (123 loc) · 4.17 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
'''
Given a directed graph G (can contain sub graphs and cycles),
find the minimum number of vertices from which all nodes are reachable.
For example:
Nodes:
0, 1, 2, 3, 4, 5
Edges:
1 <- 0
0 <- 1 <- 2
3 <- 1 <- 2
2 <- 5
4 <- 5
Representation:
--> 4
/
5 --> 2 --> 1 <--> 0
\
--> 3
Matrix:
g = [[1, 1, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 1],
[0, 1, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1]]
Return 1 (node number 5). From node number 5 all other nodes are reachable.
If we remove edge 2 <- 5, the result is 2, because we need at least nodes number 5 and 2 to visit all nodes.
Representation of the graph if we remove the edge between nodes 2 and 5.
5 --> 4
2 --> 1 <--> 0
\
--> 3
'''
class Solution(object):
def __init__(self):
self.hash = {}
self.pickedVertices = []
self.visited = None
def dfs(self, graph, vertex, visited, numberOfVisited):
visited[vertex] = 1
for i in range(len(graph[vertex])):
if(graph[vertex][i] == 1 and i != vertex and visited[i] == 0):
numberOfVisited[0] = numberOfVisited[0] +1
self.dfs(graph, i, visited, numberOfVisited)
def fillHash(self, graph):
for vertex in range(len(graph)):
self.visited = [0 for i in range(len(graph))]
numberOfVisited = [1]
self.dfs(graph, vertex, self.visited, numberOfVisited)
# if at any time a vertex can visite all vertices return 1 since we are looking for number of vertices and not the vertex it self.
if(numberOfVisited[0] == len(graph)):
return 1
self.hash[vertex] = [numberOfVisited[0], self.visited]
return 0
# if it coveres even one single vertex that has not been covered before then we return true
def coversVerticesThatHaveNotBeenCoveredBefore(self, visitedByOtherVertex, visited):
flag = False
numberOfNewVerticesCovered = 0
new_visited = visited[:]
for i in range(len(visited)):
if(visited[i] == 0 and visitedByOtherVertex[i] == 1):
flag = True
numberOfNewVerticesCovered = numberOfNewVerticesCovered + 1
new_visited[i] = 1
return flag, numberOfNewVerticesCovered, new_visited
def findVertex(self, vertex, visited, numberOfCoveredVertices, vertexList, output):
if(numberOfCoveredVertices == len(self.hash)):
output.append(vertexList[:])
for otherVertex in self.hash:
if not(otherVertex in vertexList):
flag, numberOfNewVerticesCovered, new_visited = self.coversVerticesThatHaveNotBeenCoveredBefore(self.hash[otherVertex][1], visited)
if(flag):
vertexList.append(otherVertex)
self.findVertex(otherVertex, new_visited, numberOfCoveredVertices+numberOfNewVerticesCovered, vertexList, output)
vertexList.pop()
def logic(self, graph):
if(self.fillHash(graph) == 1):
return 1
minSet = None
for vertex in self.hash:
output = []
self.findVertex(vertex, self.hash[vertex][1], self.hash[vertex][0], [vertex], output)
# find list of vertices with min length
for vertices in output:
if(not minSet or len(minSet) > len(vertices)):
minSet = vertices
return len(minSet)
#Main
'''
g1
--> 4
/
5 --> 2 --> 1 <--> 0
\
--> 3
'''
g1 = [[1, 1, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0],
[0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 1, 1]]
'''
g2
5 --> 4
2 --> 1 <--> 0
\
--> 3
'''
g2 = [
[1, 1, 0, 0, 0, 0],
[1, 1, 0, 1, 0, 0],
[0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 1]
]
g3 = [[1, 0],
[0, 1]]
g4 = [[1, 0],
[1, 1]]
obj = Solution()
print obj.logic(g4)