From 0b3450228c0d18ab21950a45890e82b723efdf66 Mon Sep 17 00:00:00 2001 From: firoz Syed Date: Sat, 15 Feb 2025 20:12:08 -0800 Subject: [PATCH 1/2] firoz graph3 completed --- DistributeWaterInVillage.java | 62 ++++++++++++++++++++++++++++++++ FindCelebrity.java | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 DistributeWaterInVillage.java create mode 100644 FindCelebrity.java diff --git a/DistributeWaterInVillage.java b/DistributeWaterInVillage.java new file mode 100644 index 0000000..19510f8 --- /dev/null +++ b/DistributeWaterInVillage.java @@ -0,0 +1,62 @@ +// 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 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]; + } +} \ No newline at end of file diff --git a/FindCelebrity.java b/FindCelebrity.java new file mode 100644 index 0000000..4928ae6 --- /dev/null +++ b/FindCelebrity.java @@ -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 Date: Sat, 15 Feb 2025 21:20:28 -0800 Subject: [PATCH 2/2] prim's algorithm --- DistributeWaterInVillage.java | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/DistributeWaterInVillage.java b/DistributeWaterInVillage.java index 19510f8..c03f392 100644 --- a/DistributeWaterInVillage.java +++ b/DistributeWaterInVillage.java @@ -59,4 +59,59 @@ private int find(int x){ 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 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> 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 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; + + } } \ No newline at end of file