Skip to content

Commit 2005be4

Browse files
committed
BuildOrder: done, time complexity: pending
1 parent 083f426 commit 2005be4

File tree

3 files changed

+211
-67
lines changed

3 files changed

+211
-67
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,136 @@
11
package com.ctci.treesandgraphs;
22

3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.HashSet;
6+
import java.util.LinkedHashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import java.util.stream.Stream;
11+
312
/**
413
* @author rampatra
514
* @since 2019-02-21
615
*/
716
public class BuildOrder {
817

9-
// todo
10-
18+
private class Project {
19+
String name;
20+
Set<Project> dependencies = new HashSet<>();
21+
22+
Project(String name) {
23+
this.name = name;
24+
}
25+
26+
@Override
27+
public String toString() {
28+
return name;
29+
}
30+
}
31+
32+
private final Map<String, Project> projects = new HashMap<>();
33+
34+
private void addProjects(Stream<String> projectNames) {
35+
projectNames.forEach(name -> projects.put(name, new Project(name)));
36+
}
37+
38+
/**
39+
* Adds a directed edge from {@code projectName2} to {@code ProjectName1}. This means {@code projectName2} is
40+
* dependent on {@code projectName1}, i.e, {@code projectName1} has to be built before {@code projectName2}.
41+
*
42+
* @param projectName1 name of project 1
43+
* @param projectName2 name of project 2
44+
*/
45+
private void addDependency(String projectName1, String projectName2) {
46+
Project p1 = projects.get(projectName1);
47+
Project p2 = projects.get(projectName2);
48+
49+
if (p1 == null) {
50+
p1 = new Project(projectName1);
51+
projects.put(projectName1, p1);
52+
}
53+
if (p2 == null) {
54+
p2 = new Project(projectName2);
55+
projects.put(projectName2, p2);
56+
}
57+
58+
p2.dependencies.add(p1);
59+
}
60+
61+
/**
62+
* Determines the order in which the projects need to be built.
63+
* Time complexity: TODO
64+
*
65+
* @return a list of projects in the order they should be built, the first project should be built first and so on.
66+
*/
67+
private List<Project> getBuildOrder() {
68+
Map<String, Project> projectsBuilt = new LinkedHashMap<>(); // linked hashmap is needed to maintain the insertion order
69+
70+
while (projectsBuilt.size() != projects.size()) {
71+
// find the projects which are not dependent on any project
72+
Set<Project> nextProjectsToBuild = getProjectsWithNoDependencies(projectsBuilt);
73+
74+
// if there are no further independent projects to build, then we can't proceed further
75+
if (nextProjectsToBuild.size() == 0) {
76+
throw new IllegalStateException("Error: Projects can't be built.");
77+
}
78+
nextProjectsToBuild.forEach(p -> projectsBuilt.put(p.name, p));
79+
80+
// once a project is built, remove the dependencies from all other projects dependent on this
81+
removeDependency(nextProjectsToBuild);
82+
}
83+
84+
return new ArrayList<>(projectsBuilt.values());
85+
}
86+
87+
private Set<Project> getProjectsWithNoDependencies(Map<String, Project> alreadyBuildProjects) {
88+
Set<Project> unBuiltProjectsWithZeroDependencies = new HashSet<>();
89+
90+
for (Map.Entry<String, Project> entry : projects.entrySet()) {
91+
if (entry.getValue().dependencies.size() == 0 && alreadyBuildProjects.get(entry.getKey()) == null) {
92+
unBuiltProjectsWithZeroDependencies.add(entry.getValue());
93+
}
94+
}
95+
96+
return unBuiltProjectsWithZeroDependencies;
97+
}
98+
99+
private void removeDependency(Set<Project> newlyBuiltProjects) {
100+
projects.forEach((n, p) -> p.dependencies.removeAll(newlyBuiltProjects));
101+
}
102+
103+
11104
public static void main(String[] args) {
105+
/* test case 1
12106
107+
––––––––––– b
108+
| ↑
109+
↓ |
110+
f <–– a <–– d <–– c
111+
112+
113+
*/
114+
BuildOrder buildOrder = new BuildOrder();
115+
buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f"));
116+
buildOrder.addDependency("a", "d");
117+
buildOrder.addDependency("f", "b");
118+
buildOrder.addDependency("b", "d");
119+
buildOrder.addDependency("f", "a");
120+
buildOrder.addDependency("d", "c");
121+
System.out.println(buildOrder.getBuildOrder());
122+
123+
// test case 2
124+
buildOrder = new BuildOrder();
125+
buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f", "g"));
126+
buildOrder.addDependency("d", "g");
127+
buildOrder.addDependency("f", "b");
128+
buildOrder.addDependency("f", "c");
129+
buildOrder.addDependency("f", "a");
130+
buildOrder.addDependency("c", "a");
131+
buildOrder.addDependency("b", "a");
132+
buildOrder.addDependency("b", "e");
133+
buildOrder.addDependency("a", "e");
134+
System.out.println(buildOrder.getBuildOrder());
13135
}
14-
}
136+
}

src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java

+64-64
Original file line numberDiff line numberDiff line change
@@ -13,82 +13,82 @@
1313
*/
1414
public class RouteBetweenNodes {
1515

16-
public static void main(String[] args) {
17-
Graph g = new Graph();
18-
g.addEdge(1, 2);
19-
g.addEdge(2, 3);
20-
g.addEdge(4, 5);
21-
g.addEdge(5, 6);
22-
System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2));
23-
System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5));
24-
System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3));
25-
System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6));
26-
System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4));
27-
System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5));
28-
}
29-
}
16+
class Graph {
3017

31-
class Graph {
18+
private final Map<Integer, GraphNode> nodes = new HashMap<>();
3219

33-
private static final Map<Integer, GraphNode> nodes = new HashMap<>();
20+
/**
21+
* Adds an edge from a node with value {@code v1} to another node with value {@code v2}.
22+
* Note: This code doesn't work for nodes having duplicate values.
23+
*
24+
* @param v1
25+
* @param v2
26+
*/
27+
void addEdge(int v1, int v2) {
28+
GraphNode n1 = nodes.get(v1);
29+
GraphNode n2 = nodes.get(v2);
3430

35-
/**
36-
* Adds an edge from a node with value {@code v1} to another node with value {@code v2}.
37-
* Note: This code doesn't work for nodes having duplicate values.
38-
*
39-
* @param v1
40-
* @param v2
41-
*/
42-
void addEdge(int v1, int v2) {
43-
GraphNode n1 = nodes.get(v1);
44-
GraphNode n2 = nodes.get(v2);
31+
if (n1 == null) {
32+
n1 = new GraphNode(v1);
33+
nodes.put(v1, n1);
34+
}
35+
if (n2 == null) {
36+
n2 = new GraphNode(v2);
37+
nodes.put(v2, n2);
38+
}
4539

46-
if (n1 == null) {
47-
n1 = new GraphNode(v1);
48-
nodes.put(v1, n1);
40+
n1.adjacent.add(n2); // as it is a directed graph
4941
}
50-
if (n2 == null) {
51-
n2 = new GraphNode(v2);
52-
nodes.put(v2, n2);
53-
}
54-
55-
n1.adjacent.add(n2); // as it is a directed graph
56-
}
5742

58-
/**
59-
* Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first
60-
* manner. Note: This code doesn't work for nodes having duplicate values.
61-
*
62-
* @param v1 the value of the first node or starting node.
63-
* @param v2 the value of the ending node.
64-
* @return {@code true} if path exists, {@code false} otherwise.
65-
*/
66-
boolean isRoutePresent(int v1, int v2) {
67-
Queue<GraphNode> queue = new ArrayDeque<>();
68-
Set<GraphNode> visited = new HashSet<>();
43+
/**
44+
* Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first
45+
* manner. Note: This code doesn't work for nodes having duplicate values.
46+
*
47+
* @param v1 the value of the first node or starting node.
48+
* @param v2 the value of the ending node.
49+
* @return {@code true} if path exists, {@code false} otherwise.
50+
*/
51+
boolean isRoutePresent(int v1, int v2) {
52+
Queue<GraphNode> queue = new ArrayDeque<>();
53+
Set<GraphNode> visited = new HashSet<>();
6954

70-
GraphNode n1 = nodes.get(v1);
71-
GraphNode n2 = nodes.get(v2);
55+
GraphNode n1 = nodes.get(v1);
56+
GraphNode n2 = nodes.get(v2);
7257

73-
if (n1 == null || n2 == null) {
74-
return false;
75-
}
58+
if (n1 == null || n2 == null) {
59+
return false;
60+
}
7661

77-
queue.add(n1);
62+
queue.add(n1);
7863

79-
while (!queue.isEmpty()) {
80-
GraphNode n = queue.poll();
64+
while (!queue.isEmpty()) {
65+
GraphNode n = queue.poll();
8166

82-
if (visited.contains(n)) {
83-
continue;
84-
}
85-
if (n.adjacent.contains(n2)) {
86-
return true;
67+
if (visited.contains(n)) {
68+
continue;
69+
}
70+
if (n.adjacent.contains(n2)) {
71+
return true;
72+
}
73+
queue.addAll(n.adjacent);
74+
visited.add(n);
8775
}
88-
queue.addAll(n.adjacent);
89-
visited.add(n);
76+
77+
return false;
9078
}
79+
}
9180

92-
return false;
81+
public static void main(String[] args) {
82+
Graph g = new RouteBetweenNodes().new Graph();
83+
g.addEdge(1, 2);
84+
g.addEdge(2, 3);
85+
g.addEdge(4, 5);
86+
g.addEdge(5, 6);
87+
System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2));
88+
System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5));
89+
System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3));
90+
System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6));
91+
System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4));
92+
System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5));
9393
}
94-
}
94+
}

src/main/java/com/rampatra/database/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
# Relational Database (WIP)
22

3+
A __relational database__ is a digital database based on
4+
the [relational model](https://en.wikipedia.org/wiki/Relational_model) of
5+
data. In simple words, it is a collection of data items with pre-defined
6+
relationships between them. These items are organized as a set of tables,
7+
with columns and rows. Each column stores some specific attribute of an object/entity and the
8+
row represents a specific object/entity.
9+
10+
A software system used to maintain relational databases is a __relational
11+
database management system (RDBMS)__, for e.g., MySQL, Oracle DB, PostgreSQL, etc.
12+
Virtually all relational database systems use __SQL (Structured Query Language)__
13+
for querying and maintaining the database.
14+
15+
## Basic Definitions
16+
17+
1. Primary Key
18+
19+
2. Candidate Key
20+
21+
3. Composite Key
22+
23+
4. Prime/Non-prime attribute
24+
325
## Types of SQL commands
426

527
1. DDL

0 commit comments

Comments
 (0)