Skip to content
This repository was archived by the owner on Sep 6, 2024. It is now read-only.
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Question 1.
* Social network connectivity. Given a social network containing n members and
* a log file containing m timestamps at which times pairs of members formed
* friendships, design an algorithm to determine the earliest time at which
* all members are connected(i.e., every member is a friend of a friend of a
* friend ... of a friend). Assume that the log file is sorted by timestamp
* and that friendship is an equivalence relation. The running time of your
* algorithm should be m*log(n) or better and use extra space proportional to n.
*/
public class SocialNetworkConnectivity {
private final int[] parent;
private int counter;

/**
* Create a union-find structure with size n and initialize counter.
* @param n number of network members.
*/
public SocialNetworkConnectivity(int n) {
parent = new int[n];
counter = n;
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}

/**
* Return true then all people is connected.
* @return true if all people connected otherwise false.
*/
public boolean isAllMembersConnected() {
return counter == 1;
}

/**
* Form a friend between two people.
* @param p one element
* @param q the other element
*/
public void formAFriendship(int p, int q) {
union(p, q);
}

private void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP != rootQ) {
parent[rootQ] = rootP;
counter--;
}
}

private int find(int p) {
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Question 2.
* Union-find with specific canonical element. Add a method <code>find()</code>
* to the union-find data type so that <code>find(i)</code> returns the
* largest element in the connected component containing <code>i</code>. The
* operations, <code>union()</code>, <code>connected()</code>, and
* <code>find()</code> should all take logarithmic time or better.
* For example, if one of the connected components is <code>{1,2,6,9}</code>,
* then the <code>find()</code> method should return 9 for each of the four
* elements in the connected components.
*/
public class SpecificCanonicalElementUF {
private final int[] parent;
private final int[] size;
private final int[] maxValue;

/**
* Create union-find structure with auxiliary array containing maximal
* value of each connected group.
* @param n size of structure.
*/
public SpecificCanonicalElementUF(int n) {
parent = new int[n];
size = new int[n];
maxValue = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
maxValue[i] = i;
}
}

/**
* Returns the largest element of the set containing element {@code p}.
* @param i an element.
* @return the canonical element of the set containing {@code p}.
* @throws IllegalArgumentException unless {@code 0 <= p < n}.
*/
public int find(int i) {
return maxValue[findRoot(i)];
}

/**
* Merges the set containing element {@code p} with the the set
* containing element {@code q}. Also choose final root depending on size
* of tree. Use maxValue to store maximal value.
* @param p one element.
* @param q the other element.
*/
public void union(int p, int q) {
int rootP = findRoot(p);
int rootQ = findRoot(q);
if (rootP == rootQ) return;

if (size[rootP] < size[rootQ]) {
parent[rootP] = rootQ;
maxValue[rootQ] = Math.max(maxValue[rootP], maxValue[rootQ]);
size[rootQ] += size[rootP];
} else {
parent[rootQ] = rootP;
maxValue[rootP] = Math.max(maxValue[rootP], maxValue[rootQ]);
size[rootP] += size[rootQ];
}
}

private int findRoot(int p) {
while (p != parent[p]) {
parent[p] = parent[parent[p]];
maxValue[p] = maxValue[parent[p]];
p = parent[p];
}
return p;
}
}
62 changes: 62 additions & 0 deletions Algorithms, Part I/Week 1/Union-Find/SuccessorWithDelete.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Successor with delete. Given a set of n integers S = {0, 1, ..., n − 1} and a
* sequence of requests of the following form:
* <ul>
* <li>Remove x from S
* <li>Find the successor of x: the smallest y in S such that y ≥ x.
* </ul>
* design a data type so that all operations (except construction) take
* logarithmic time or better in the worst case.
*/
public class SuccessorWithDelete {
private final int[] parent;
private final int[] size;

/**
* Initialize set of n integers S = {0, 1, ...,n − 1}.
* @param n - size of set.
*/
public SuccessorWithDelete(int n) {
parent = new int[n];
size = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}

/**
* Remove number x from set if cell value is equal cell number.
* @param x is the number to be removed.
*/
public void remove(int x) {
if (x == parent[x]) {
union(x + 1, x);
}
}

/**
* Find a successor of number x.
* @param x is the number to find successor.
* @return smallest number in parent such that number ≥ x.
*/
public int successor(int x) {
return find(x);
}

private void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP != rootQ) {
parent[rootQ] = rootP;
}
}

private int find(int p) {
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
}