Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
7oSkaaa committed May 21, 2023
2 parents a9e6880 + 839a065 commit 59767b6
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Author: Lama Salah

/*
-- THE IDEA --
Use depth-first search to traverse the graph represented by the equations and values.
Perform divisions based on the values encountered during the traversal.
Store the results in a vector and return it as the output.
----------------------------------
Step 1:
Define two maps: 'adj' and 'vis'.
- 'adj' is a mapping from a string (variable) to a vector of pairs.
Each pair contains another string and its corresponding double value.
- 'vis' is a mapping from a string to a boolean value, indicating whether the variable has been visited
during the depth-first search (DFS) traversal.
----------------------------------
Step 2:
Define a 'dfs' function that performs a depth-first search from the source variable 'src' to the destination variable 'des'.
The function returns a double value representing the division result of reaching 'des' from 'src'.
----------------------------------
Step 3:
In the `calcEquation` function:
- Iterate over the 'equations' and 'values' vectors to build the adjacency list.
- For each equation, add an entry in the adjacency list for both variables ('equations[i][0]' and 'equations[i][1]'),
along with the corresponding value (values[i]) and its reciprocal (1 / values[i]).
- Initialize a vector 'ans' to store the results of the queries.
- Iterate over the 'queries' vector and perform the following steps for each query:
- Clear the 'vis' map to mark all variables as unvisited.
- Call the 'dfs' function with the source and destination variables from the current query.
- Check if the destination variable was not visited during the DFS traversal.
If so, set the result 'ans[i]' to -1; otherwise, set it to the result of the DFS traversal.
----------------------------------
Step 4:
Return the vector 'ans' (the results of the queries).
*/


// -- Code --

class Solution {
public:
map<string, vector<pair<string, double>>> adj; // Adjacency list to represent the graph.
map<string, bool> vis; // Map to track visited variables during DFS.

double dfs(string src, string des) {
vis[src] = true; // Mark the current variable as visited.

if (src == des) {
// If the source variable is in the adjacency list, return 1; otherwise, return -1.
return adj.count(src) ? 1 : -1;
}

double ans = 1; // Initialize the answer as 1.

// Traverse through the adjacency list of the current variable.
for (auto& [i, j] : adj[src]) {
if (!vis[i] && !vis[des]) {
// Recursively call dfs on unvisited variables and update the answer.
ans = j * dfs(i, des);
}
}

return ans; // Return the answer.
}

vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
// Build the adjacency list.
for (int i = 0; i < equations.size(); i++) {
adj[equations[i][0]].push_back({ equations[i][1], values[i] });
adj[equations[i][1]].push_back({ equations[i][0], 1 / values[i] });
}

vector<double> ans(queries.size()); // Initialize the result vector.

// Evaluate each query.
for (int i = 0; i < queries.size(); i++) {
vis.clear(); // Clear the visited map for each query.

// Perform DFS to calculate the division result.
double x = dfs(queries[i][0], queries[i][1]);

// If the destination variable was not visited, set the result to -1;
// otherwise, set it to the division result.
ans[i] = !vis[queries[i][1]] ? -1 : x;
}

return ans; // Return the answers to all queries.
}
};
52 changes: 52 additions & 0 deletions 05- May/21- Shortest Bridge/21- Shortest Bridge (Ahmed Hossam).cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Author: Ahmed Hossam

class Solution {

int n;
vector < vector < int > > grid;

// Check if the current position (r, c) is a valid position for island expansion
bool is_valid(int r, int c, set < pair < int, int > >& isL) {
return min(r, c) >= 0 && max(r, c) < n && !isL.count({r, c}) && grid[r][c];
}

// Depth-first search to expand the island
void dfs(int r, int c, set < pair < int, int > >& isL) {
if (!is_valid(r, c, isL)) return;
isL.insert({r, c}); // Mark the current position as visited
grid[r][c] = 0; // Set the current position as water
dfs(r + 1, c, isL); // Check the bottom position
dfs(r - 1, c, isL); // Check the top position
dfs(r, c + 1, isL); // Check the right position
dfs(r, c - 1, isL); // Check the left position
}

public:
int shortestBridge(vector<vector<int>>& grid) {
this -> n = grid.size();
this -> grid = grid;

set < pair < int, int > > isl1, isl2; // Sets to store the positions of the two islands
bool isL = true; // Flag to differentiate between the two islands

for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
if (grid[x][y]) {
if (isL)
dfs(x, y, isl1), isL = false; // Expand the first island
else
dfs(x, y, isl2); // Expand the second island
}
}
}

int ans = INT_MAX;
for (auto [x1, y1] : isl1)
for (auto [x2, y2] : isl2)
ans = min(ans, abs(x1 - x2) + abs(y1 - y2) - 1); // Calculate the minimum distance between the two islands


return ans;
}
};

69 changes: 69 additions & 0 deletions 05- May/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
1. **[Minimum Number of Vertices to Reach All Nodes](#18--minimum-number-of-vertices-to-reach-all-nodes)**
1. **[Is Graph Bipartite?](#19--is-graph-bipartite)**
1. **[Evaluate Division](#20--evaluate-division)**
1. **[Shortest Bridge](#21--shortest-bridge)**

<hr>
<br><br>
Expand Down Expand Up @@ -1121,4 +1122,72 @@ public:
}
};
```

<hr>
<br><br>

## 21) [Shortest Bridge](https://leetcode.com/problems/shortest-bridge/)

### Difficulty

![](https://img.shields.io/badge/Medium-orange?style=for-the-badge)

### Related Topic

`Array` `Depth-First Search` `Breadth-First Search` `Matrix`

### Code


```cpp
class Solution {

int n;
vector < vector < int > > grid;

// Check if the current position (r, c) is a valid position for island expansion
bool is_valid(int r, int c, set < pair < int, int > >& isL) {
return min(r, c) >= 0 && max(r, c) < n && !isL.count({r, c}) && grid[r][c];
}

// Depth-first search to expand the island
void dfs(int r, int c, set < pair < int, int > >& isL) {
if (!is_valid(r, c, isL)) return;
isL.insert({r, c}); // Mark the current position as visited
grid[r][c] = 0; // Set the current position as water
dfs(r + 1, c, isL); // Check the bottom position
dfs(r - 1, c, isL); // Check the top position
dfs(r, c + 1, isL); // Check the right position
dfs(r, c - 1, isL); // Check the left position
}

public:
int shortestBridge(vector<vector<int>>& grid) {
this -> n = grid.size();
this -> grid = grid;

set < pair < int, int > > isl1, isl2; // Sets to store the positions of the two islands
bool isL = true; // Flag to differentiate between the two islands

for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
if (grid[x][y]) {
if (isL)
dfs(x, y, isl1), isL = false; // Expand the first island
else
dfs(x, y, isl2); // Expand the second island
}
}
}

int ans = INT_MAX;
for (auto [x1, y1] : isl1)
for (auto [x2, y2] : isl2)
ans = min(ans, abs(x1 - x2) + abs(y1 - y2) - 1); // Calculate the minimum distance between the two islands

return ans;
}
};
```

0 comments on commit 59767b6

Please sign in to comment.