Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Exercise_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# S30 Problem #216 Optimize Water Distribution in a Village
#LeetCode #1168 https://leetcode.com/problems/optimize-water-distribution-in-a-village/

# Author : Akaash Trivedi
# Did this code successfully run on Leetcode : Yes #
# Any problem you faced while coding this : No

# union find technique
# connect the village node to a dummy node 0 with cost of wells as edge
# add pipe to edges and sort them according to cost
# use union find to connect each nodes until all nodes are connected and return result
# TC: O(E log E) Here E = edges
# SC: O(E + V)
class Solution:
def minCostToSupplyWater(self, n: int, wells: List[int], pipes: List[List[int]]) -> int:
edges = []
uf = [] # union find
for i in range(n+1):
uf.append(i)
# make a dummy node 0 and draw edges from it to each node and give well cost
for i in range(1,n+1):
# edge from 0 to, node, cost of well
edges.append((0, i, wells[i-1]))

# add pipes cost to edges
edges.extend(pipes)
edges.sort(key=lambda x:x[2])
print(edges)

res = 0
for edge in edges:
x, y = edge[0], edge[1]
px = self.find(uf, x) # parent x
py = self.find(uf, y) # parent y

if px != py:
res += edge[2]
uf[py] = px

return res

# function to find ulimate parent
def find(self, uf, x):
# base
if x != uf[x]:
uf[x] = self.find(uf, uf[x])
return uf[x]
84 changes: 84 additions & 0 deletions Exercise_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# S30 Problem #194 find celebrity
#LeetCode #277 https://leetcode.com/problems/find-the-celebrity/description/

# Author : Akaash Trivedi
# Did this code successfully run on Leetcode : Yes #
# Any problem you faced while coding this : No

# The knows API is already defined for you.
# return a bool, whether a knows b
# def knows(a: int, b: int) -> bool:

# topological sort
# indegrees array: (a,b) a knows b
# increase the indegree of person b and degreees indegree of person a
# Person whos indegree is n-1, meaning that everyone knows that person => celebrity
# TC: O(n^2)
# SC: O(n)
class Solution:
def findCelebrity(self, n: int) -> int:
indegree = [0] * n

for i in range(n):
for j in range(n):
if i == j: continue
if knows(i, j):
# increase the j's indegree and decrease i's
indegree[j] += 1
indegree[i] -= 1

# anyone has indegree n-1, means everyone knows that person
for i in range(n):
if indegree[i] == n - 1:
return i

return -1


# linear 3n solution
# Assume one of them is a celeb, and update the celeb when they knows someone
# after 1st pass, we found some celeb: check if everyone knows celeb; celeb knows no one
# return the celeb, if not return -1
# TC: O(n)
# SC: O(1)

class Solution:
def findCelebrity(self, n: int) -> int:
celeb = 0 # assume starting with 0 is celebrity
for i in range(1, n):
if knows(celeb, i):
# celebrity cant know anyone, move the celebrity to i
celeb = i

# celeberity should not know anyone and everyone should know celeb
for i in range(n):
if i == celeb:continue
if not knows(i, celeb) or knows(celeb, i):
return -1

return celeb


# linear 3n solution - little faster
# Assume one of them is a celeb, and update the celeb when they knows someone
# after 1st pass, we found some celeb: check if everyone knows celeb; celeb knows no one
# return the celeb, if not return -1
# TC: O(n)
# SC: O(1)

class Solution:
def findCelebrity(self, n: int) -> int:
celeb = 0 # assume starting with 0 is celebrity
for i in range(1, n):
if knows(celeb, i):
# celebrity cant know anyone, move the celebrity to i
celeb = i

# celeberity should not know anyone and everyone should know celeb
for i in range(n):
if i == celeb:continue
if not knows(i, celeb):
return -1
if i < celeb and knows(celeb, i):
return -1
return celeb