Skip to content

Commit

Permalink
add solutions, explanation and update the README file of the day of 684
Browse files Browse the repository at this point in the history
  • Loading branch information
Aarzoo committed Jan 28, 2025
1 parent 0e7f8de commit 5f6d8d0
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions Algorithms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
| 650 | 2 Keys Keyboard | [C++](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.cpp), [Java](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.java), [JavaScript](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.js), [Python](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.py), [Go](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.go) | [Explanation](./Algorithms/src/650.%202%20Keys%20Keyboard/Explanation/explanation.md) | Medium |
| 664 | Strange Printer | [C++](./Algorithms/src/664.%20Strange%20Printer/Code/solution.cpp), [Java](./Algorithms/src/664.%20Strange%20Printer/Code/solution.java), [JavaScript](./Algorithms/src/664.%20Strange%20Printer/Code/solution.js), [Python](./Algorithms/src/664.%20Strange%20Printer/Code/solution.py), [Go](./Algorithms/src/664.%20Strange%20Printer/Code/solution.go) | [Explanation](./Algorithms/src/664.%20Strange%20Printer/Explanation/explanation.md) | Hard |
| 670 | Maximum Swap | [C++](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.cpp), [Java](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.java), [JavaScript](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.js), [Python](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.py), [Go](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.go) | [Explanation](./Algorithms/src/670.%20Maximum%20Swap/Explanation/explanation.md) | Medium |
| 684 | Redundant Connection | [C++](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.cpp), [Java](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.java), [JavaScript](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.js), [Python](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.py), [Go](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.go) | [Explanation](./Algorithms/src/684.%20Redundant%20Connection/Explanation/explanation.md) | Medium |
| 703 | Kth Largest Element in a Stream | [C++](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.cpp), [Java](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.java), [JavaScript](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.js), [Python](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.py), [Go](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.go) | [Explanation](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Explanation/explanation.md) | Easy |
| 719 | Find K-th Smallest Pair Distance | [C++](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.cpp), [Java](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.java), [JavaScript](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.js), [Python](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.py), [Go](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.go) | [Explanation](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Explanation/explanation.md) | Hard |
| 729 | My Calendar I | [C++](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.cpp), [Java](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.java), [JavaScript](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.js), [Python](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.py), [Go](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.go) | [Explanation](./Algorithms/src/729.%20My%20Calendar%20I/Explanation/explanation.md) | Medium |
Expand Down
49 changes: 49 additions & 0 deletions Algorithms/src/684. Redundant Connection/Code/solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class Solution
{
public:
vector<int> findRedundantConnection(vector<vector<int>> &edges)
{
int n = edges.size();
vector<int> parent(n + 1), rank(n + 1, 0);

// Initialize each node as its own parent
for (int i = 0; i <= n; i++)
{
parent[i] = i;
}

// Find function with path compression
function<int(int)> find = [&](int node)
{
if (parent[node] != node)
parent[node] = find(parent[node]); // Path compression
return parent[node];
};

// Union function by rank
auto unionSets = [&](int u, int v)
{
int rootU = find(u), rootV = find(v);
if (rootU == rootV)
return false; // Cycle detected
if (rank[rootU] > rank[rootV])
parent[rootV] = rootU;
else if (rank[rootU] < rank[rootV])
parent[rootU] = rootV;
else
{
parent[rootV] = rootU;
rank[rootU]++;
}
return true;
};

// Process each edge
for (auto &edge : edges)
{
if (!unionSets(edge[0], edge[1]))
return edge;
}
return {};
}
};
39 changes: 39 additions & 0 deletions Algorithms/src/684. Redundant Connection/Code/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
func findRedundantConnection(edges [][]int) []int {
parent := make([]int, len(edges)+1)
rank := make([]int, len(edges)+1)

for i := range parent {
parent[i] = i
}

var find func(int) int
find = func(node int) int {
if parent[node] != node {
parent[node] = find(parent[node])
}
return parent[node]
}

union := func(u, v int) bool {
rootU, rootV := find(u), find(v)
if rootU == rootV {
return false
}
if rank[rootU] > rank[rootV] {
parent[rootV] = rootU
} else if rank[rootU] < rank[rootV] {
parent[rootU] = rootV
} else {
parent[rootV] = rootU
rank[rootU]++
}
return true
}

for _, edge := range edges {
if !union(edge[0], edge[1]) {
return edge
}
}
return nil
}
41 changes: 41 additions & 0 deletions Algorithms/src/684. Redundant Connection/Code/solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class Solution {
public int[] findRedundantConnection(int[][] edges) {
int n = edges.length;
int[] parent = new int[n + 1];
int[] rank = new int[n + 1];

for (int i = 0; i <= n; i++) {
parent[i] = i;
rank[i] = 0;
}

// Find function with path compression
int find(int node) {
if (parent[node] != node)
parent[node] = find(parent[node]);
return parent[node];
}

// Union function by rank
boolean unionSets(int u, int v) {
int rootU = find(u);
int rootV = find(v);
if (rootU == rootV) return false;
if (rank[rootU] > rank[rootV])
parent[rootV] = rootU;
else if (rank[rootU] < rank[rootV])
parent[rootU] = rootV;
else {
parent[rootV] = rootU;
rank[rootU]++;
}
return true;
}

// Process each edge
for (int[] edge : edges) {
if (!unionSets(edge[0], edge[1])) return edge;
}
return new int[0];
}
}
29 changes: 29 additions & 0 deletions Algorithms/src/684. Redundant Connection/Code/solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var findRedundantConnection = function (edges) {
let parent = Array(edges.length + 1)
.fill(0)
.map((_, i) => i);
let rank = Array(edges.length + 1).fill(0);

function find(node) {
if (parent[node] !== node) parent[node] = find(parent[node]); // Path compression
return parent[node];
}

function union(u, v) {
let rootU = find(u),
rootV = find(v);
if (rootU === rootV) return false;
if (rank[rootU] > rank[rootV]) parent[rootV] = rootU;
else if (rank[rootU] < rank[rootV]) parent[rootU] = rootV;
else {
parent[rootV] = rootU;
rank[rootU]++;
}
return true;
}

for (let [u, v] of edges) {
if (!union(u, v)) return [u, v];
}
return [];
};
29 changes: 29 additions & 0 deletions Algorithms/src/684. Redundant Connection/Code/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import List

class Solution:
def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
parent = list(range(len(edges) + 1))
rank = [0] * (len(edges) + 1)

def find(node):
if parent[node] != node:
parent[node] = find(parent[node]) # Path compression
return parent[node]

def union(u, v):
rootU, rootV = find(u), find(v)
if rootU == rootV:
return False # Cycle detected
if rank[rootU] > rank[rootV]:
parent[rootV] = rootU
elif rank[rootU] < rank[rootV]:
parent[rootU] = rootV
else:
parent[rootV] = rootU
rank[rootU] += 1
return True

for u, v in edges:
if not union(u, v):
return [u, v]
return []
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# **Intuition**

When I first saw this problem, it reminded me of a cycle detection problem in an undirected graph. The problem states that we have a connected graph with **n nodes** and **n edges** (i.e., a tree with an extra edge).

A **tree** with `n` nodes should have exactly `n-1` edges. Since we have `n` edges, this means there's **one extra edge** forming a cycle, and we need to **find and remove that extra edge** while keeping the graph connected.

A common way to handle **cycle detection in an undirected graph** is by using **Union-Find (Disjoint Set Union, DSU)**. So, my first instinct was to solve this using **DSU with path compression and union by rank**.

---

# **Approach**

To find the **redundant edge** efficiently, we use the **Union-Find (DSU) data structure**:

1. **Initialize DSU:**
- We maintain a parent array where each node is its own parent initially.
- We also maintain a rank array for optimization.

2. **Process each edge one by one:**
- If two nodes in an edge already belong to the same connected component (i.e., they have the same root parent), then adding this edge **forms a cycle**.
- This means the current edge is **redundant**, so we return it as the answer.

3. **Union-Find operations:**
- **Find function:** Uses path compression to keep the tree flat.
- **Union function:** Uses union by rank to attach smaller trees under larger ones, keeping the structure balanced.

By iterating over all edges and performing these operations, we can efficiently detect the first edge that forms a cycle.

---

# **Complexity Analysis**

- **Time Complexity:** \(O(n \log n)\)
- The `find` and `union` operations have an **amortized** complexity of **O(α(n))**, which is nearly constant.
- Since we process `n` edges, the overall complexity is **O(n α(n))**, which simplifies to **O(n log n)** in the worst case.

- **Space Complexity:** **O(n)**
- We maintain a `parent` and `rank` array, both of size **O(n)**.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Welcome to the LeetCode Solutions repository! Here, you'll find daily solutions
| 650 | 2 Keys Keyboard | [C++](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.cpp), [Java](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.java), [JavaScript](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.js), [Python](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.py), [Go](./Algorithms/src/650.%202%20Keys%20Keyboard/Code/solution.go) | [Explanation](./Algorithms/src/650.%202%20Keys%20Keyboard/Explanation/explanation.md) | Medium |
| 664 | Strange Printer | [C++](./Algorithms/src/664.%20Strange%20Printer/Code/solution.cpp), [Java](./Algorithms/src/664.%20Strange%20Printer/Code/solution.java), [JavaScript](./Algorithms/src/664.%20Strange%20Printer/Code/solution.js), [Python](./Algorithms/src/664.%20Strange%20Printer/Code/solution.py), [Go](./Algorithms/src/664.%20Strange%20Printer/Code/solution.go) | [Explanation](./Algorithms/src/664.%20Strange%20Printer/Explanation/explanation.md) | Hard |
| 670 | Maximum Swap | [C++](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.cpp), [Java](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.java), [JavaScript](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.js), [Python](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.py), [Go](./Algorithms/src/670.%20Maximum%20Swap/Code/solution.go) | [Explanation](./Algorithms/src/670.%20Maximum%20Swap/Explanation/explanation.md) | Medium |
| 684 | Redundant Connection | [C++](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.cpp), [Java](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.java), [JavaScript](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.js), [Python](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.py), [Go](./Algorithms/src/684.%20Redundant%20Connection/Code/solution.go) | [Explanation](./Algorithms/src/684.%20Redundant%20Connection/Explanation/explanation.md) | Medium |
| 703 | Kth Largest Element in a Stream | [C++](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.cpp), [Java](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.java), [JavaScript](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.js), [Python](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.py), [Go](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Code/solution.go) | [Explanation](./Algorithms/src/703.%20Kth%20Largest%20Element%20in%20a%20Stream/Explanation/explanation.md) | Easy |
| 719 | Find K-th Smallest Pair Distance | [C++](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.cpp), [Java](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.java), [JavaScript](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.js), [Python](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.py), [Go](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Code/solution.go) | [Explanation](./Algorithms/src/719.%20Find%20K-th%20Smallest%20Pair%20Distance/Explanation/explanation.md) | Hard |
| 729 | My Calendar I | [C++](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.cpp), [Java](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.java), [JavaScript](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.js), [Python](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.py), [Go](./Algorithms/src/729.%20My%20Calendar%20I/Code/solution.go) | [Explanation](./Algorithms/src/729.%20My%20Calendar%20I/Explanation/explanation.md) | Medium |
Expand Down

0 comments on commit 5f6d8d0

Please sign in to comment.