From f77a88ef7bd503c328a50bfdd3bb6d85ad4e4407 Mon Sep 17 00:00:00 2001 From: ZapDos7 Date: Tue, 10 Jun 2025 19:24:42 +0300 Subject: [PATCH 1/2] Dijkstra showcase, weighted graph implementation --- README.md | 3 +- src/dataStructures/graphs/WeightedGraph.java | 86 ++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/dataStructures/graphs/WeightedGraph.java diff --git a/README.md b/README.md index 735e2c2..b8d4b4b 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,8 @@ ### Graphs - [x] [Terminology and Representations of Graphs](http://www.techiedelight.com/terminology-and-representations-of-graphs/) - [x] Given a list of edges and tasked to build your own graph from the edges +- [x] Implement Dijkstra’s algorithm (implemented Weighted Graph to showcase this) + ### Matrix ### Trees @@ -268,7 +270,6 @@ - Graphs - - [ ] Implement Dijkstra’s algorithm - [ ] Implement Topological sort - [ ] Implement Bellman-Ford algorithm - [ ] Implement Floyd-Warshall algorithm diff --git a/src/dataStructures/graphs/WeightedGraph.java b/src/dataStructures/graphs/WeightedGraph.java new file mode 100644 index 0000000..950af46 --- /dev/null +++ b/src/dataStructures/graphs/WeightedGraph.java @@ -0,0 +1,86 @@ +package dataStructures.graphs; + +import java.util.*; + +import dataStructures.graphs.CustomGraph.Vertex; + +public class WeightedGraph { + private Map> adjVertices; + + public static class Edge { + Vertex destination; + int weight; + + public Edge(Vertex destination, int weight) { + this.destination = destination; + this.weight = weight; + } + + @Override + public String toString() { + return "Edge{to=" + destination + ", weight=" + weight + '}'; + } + } + + public Map dijkstra(Vertex source) { + Map distances = new HashMap<>(); + Map previous = new HashMap<>(); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(vd -> vd.distance)); + + for (Vertex vertex : adjVertices.keySet()) { + distances.put(vertex, Integer.MAX_VALUE); + } + distances.put(source, 0); + pq.add(new VertexDistance(source, 0)); + + while (!pq.isEmpty()) { + VertexDistance current = pq.poll(); + Vertex u = current.vertex; + + for (Edge edge : adjVertices.getOrDefault(u, Collections.emptyList())) { + Vertex v = edge.destination; + int newDist = distances.get(u) + edge.weight; + if (newDist < distances.get(v)) { + distances.put(v, newDist); + previous.put(v, u); + pq.add(new VertexDistance(v, newDist)); + } + } + } + + return distances; + } + + private static class VertexDistance { + Vertex vertex; + int distance; + + public VertexDistance(Vertex vertex, int distance) { + this.vertex = vertex; + this.distance = distance; + } + } + + // demo + + public static void main(String[] args) { + Vertex a = new Vertex("A"); + Vertex b = new Vertex("B"); + Vertex c = new Vertex("C"); + Vertex d = new Vertex("D"); + + WeightedGraph graph = new WeightedGraph(); + graph.adjVertices = new HashMap<>(); + + graph.adjVertices.put(a, Arrays.asList(new Edge(b, 1), new Edge(c, 4))); + graph.adjVertices.put(b, Arrays.asList(new Edge(c, 2), new Edge(d, 5))); + graph.adjVertices.put(c, Arrays.asList(new Edge(d, 1))); + graph.adjVertices.put(d, new ArrayList<>()); + + Map distances = graph.dijkstra(a); + for (Map.Entry entry : distances.entrySet()) { + System.out.println("Distance from A to " + entry.getKey().label + " = " + entry.getValue()); + } + } + +} From 749118d869f75c6628977bcfccaa20f94acf0019 Mon Sep 17 00:00:00 2001 From: ZapDos7 Date: Tue, 10 Jun 2025 19:49:59 +0300 Subject: [PATCH 2/2] clone a graph --- README.md | 3 +- src/dataStructures/graphs/Node.java | 35 ++++++++++++++++ .../graphs/cloner/GraphCloner.java | 42 +++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/dataStructures/graphs/Node.java create mode 100644 src/dataStructures/graphs/cloner/GraphCloner.java diff --git a/README.md b/README.md index b8d4b4b..514f777 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ - [x] [Terminology and Representations of Graphs](http://www.techiedelight.com/terminology-and-representations-of-graphs/) - [x] Given a list of edges and tasked to build your own graph from the edges - [x] Implement Dijkstra’s algorithm (implemented Weighted Graph to showcase this) - +- [x] [Clone graph](https://leetcode.com/problems/clone-graph/) ### Matrix ### Trees @@ -275,7 +275,6 @@ - [ ] Implement Floyd-Warshall algorithm - [ ] Implement Prim’s algorithm - [ ] Implement Kruskal’s algorithm - - [ ] [Clone graph](https://leetcode.com/problems/clone-graph/) - [ ] [Course Schedule](https://leetcode.com/problems/course-schedule/) - [ ] [Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) - [ ] [Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) diff --git a/src/dataStructures/graphs/Node.java b/src/dataStructures/graphs/Node.java new file mode 100644 index 0000000..9f417dd --- /dev/null +++ b/src/dataStructures/graphs/Node.java @@ -0,0 +1,35 @@ +package dataStructures.graphs; + +import java.util.ArrayList; +import java.util.List; + +// LeetCode Node for examples +public class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList<>(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList<>(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } + + // My addition: toString() + + @Override + public String toString() { + return "Node{" + + "val=" + val + + ", neighbors=" + neighbors + + '}'; + } +} diff --git a/src/dataStructures/graphs/cloner/GraphCloner.java b/src/dataStructures/graphs/cloner/GraphCloner.java new file mode 100644 index 0000000..d59c53d --- /dev/null +++ b/src/dataStructures/graphs/cloner/GraphCloner.java @@ -0,0 +1,42 @@ +package dataStructures.graphs.cloner; + +import dataStructures.graphs.Node; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GraphCloner { + + public static void main(String[] args) { + Node n1 = new Node(1); + Node n2 = new Node(2); + n2.neighbors = List.of(n1); + Node root = new Node(0); + root.neighbors = List.of(n1, n2); + System.out.println("OG: " + root); + System.out.println("Clone: " + cloneGraph(root)); + } + + // DFS + public static Node cloneGraph(Node node) { + Map map = new HashMap<>(); + + if (node == null) return null; + + if (map.containsKey(node)) { + return map.get(node); // already cloned, use the previously cloned one + } + + // Clone the node before recursion + Node clone = new Node(node.val); // create new node with same value + map.put(node, clone); + + // Clone all the neighbors recursively + for (Node neighbor : node.neighbors) { + clone.neighbors.add(cloneGraph(neighbor)); + } + + return clone; + } +}