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
117 changes: 117 additions & 0 deletions DistributeWaterInVillage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Approach : Kruskal's ALgorithm uses union find to identify the Minimum Spanning Tree (MST). They operate on undirected graphs.
// First and foremost we need to form all the edges including pipes and wells (using n houses).
// We have to sort the edges array based on their weight/cost and then start unionizing the edges and keep track of the costs.
// In order to unionize them we need a DS to store whose parents.
// Time : E Log E
// Space :
class Solution {
int[] parent;
public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
this.parent = new int[n+1]; // 1 to n
int result = 0; // cost tracker

// Initially every node is its own parent
for(int i=1;i<=n;i++){
parent[i] = i;
}

// collect all edges
List<int[]> edges = new ArrayList<>();

for(int[] pipe : pipes){
edges.add(pipe);
}

for(int i=1;i<=n;i++){
// digging a well between 0 and 1 house , 0 and 2 house , 0 and 3 house
edges.add(new int[]{0,i,wells[i-1]});// wells - $[1,2,2]
}

Collections.sort(edges , (a,b)-> a[2] - b[2]); // sort in ascending order

// go through these edges and unionize them
for(int[] edge:edges){
int x = edge[0];
int y = edge[1];

// first identify the ultimate parent
int px = find(x);
int py = find(y);

// if ultimate parents are not the same then unionize (without any rules) with cost
if(px!=py){
result+=edge[2];
// surrender ultimate parent (py) to ultimate parent (px)
parent[py] = px;
}
}

return result;

}

private int find(int x){
// check until parent of x equal to x
if(parent[x]!=x){
// whenever recursion comes back update the ulitmate parent
parent[x]= find(parent[x]); // Path reduction
}

return parent[x];
}
}

// Approach : Prim's ALgorithm uses union heaps/priority queues to find the Minimum Spanning Tree (MST). They operate on undirected graphs.
// First and foremost we need to form all the edges including pipes and wells (using n houses).
// Time : O((N+M)⋅log(N+M))
// Space : O(N+M)
class Solution {
public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {

// collect all edges
List<int[]> edges = new ArrayList<>();

for(int[] pipe:pipes){
edges.add(pipe);
}

// digging a well between 0 and 1 house , 0 and 2 house , 0 and 3 house
for(int i=1;i<=n;i++){
edges.add(new int[]{0,i,wells[i-1]});
}

int result =0;

// In order to traverse over the graph we need an adjacency List
HashMap<Integer , List<int[]>> map = new HashMap<>();
for(int[] edge:edges){
map.putIfAbsent(edge[0],new ArrayList<>());
map.putIfAbsent(edge[1],new ArrayList<>()); // since it is a undirected graph so we need entried for both
map.get(edge[0]).add(new int[]{edge[1],edge[2]});
map.get(edge[1]).add(new int[]{edge[0],edge[2]});
}

PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->a[1]-b[1]);
pq.add(new int[]{0,0}); // need to start with well. represent well as 0 and cost of digging a well at 0 is $0 cost

boolean[] visited = new boolean[n+1];
while(!pq.isEmpty()){
int[] curr = pq.poll();
int node = curr[0];
int cost = curr[1];

if(visited[node]) continue;
visited[node] = true; // first time visiting makr it as visited and incurr the cost
// we always get min weight first - since it is heaps
result+=cost;

// go over all the neighbours - saved in map
for(int[] ne:map.get(node)){
pq.add(ne);
}
}

return result;

}
}
66 changes: 66 additions & 0 deletions FindCelebrity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Approach : Brute Force Approach.
// For every member out of n members check if they have trustees or not. If member trusts other member then he is not celebrity.
// If member being trusted by all members excpet himself (n-1) then he is the celebrity
// Build the in degrees array based out of the above. For celebrity the vaue should be n-1 and for all others it will be negative numbers
//
// Time : O(n^2)
// Space : O(n)

/* The knows API is defined in the parent class Relation.
boolean knows(int a, int b); */

public class Solution extends Relation {
public int findCelebrity(int n) {
int[] indegrees = new int[n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i == j) continue; // member's self trust we can just ignore
// i knows j -True then n degrees of i should be decremented.
if(knows(i,j)){
indegrees[i]--;
indegrees[j]++;
}
}
}

for(int k=0;k<indegrees.length;k++){
if(indegrees[k] == n-1){
return k;
}
}
return -1;
}
}

// Approach : Brute Force Approach - Optimizied.
// For every member out of n members check if they have trustees or not.
// One member does not trusted by the other member then make the other member as potential celebrity and continue to check.
// After the potential celebrity found then check relation between the clebrity with the other members who are not being trusted.
// Time : O(n) + O(n)
// Space : O(n)

/* The knows API is defined in the parent class Relation.
boolean knows(int a, int b); */

public class Solution extends Relation {
public int findCelebrity(int n) {
int potentialCeleb = 0;
for(int i =1;i<n;i++){
if(knows(potentialCeleb,i)){
potentialCeleb = i;
}
}

for(int i =0;i<n;i++){
if(i == potentialCeleb) continue; // celebrity knows himself so skip

// if any of the person does not know celebrity or
// if celebrity knows the person
if(knows(potentialCeleb,i) || !knows(i,potentialCeleb)){
return -1;
}
}

return potentialCeleb;
}
}