forked from 7oSkaaa/LeetCode_DailyChallenge_2023
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '7oSkaaa:main' into main
- Loading branch information
Showing
4 changed files
with
306 additions
and
0 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
04- April/28- Similar String Groups/28- Similar String Groups (Mahmoud Aboelsoud).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Author: Mahmoud Aboelsoud | ||
|
||
class Solution { | ||
public: | ||
// Disjoint Set Union (DSU) data structure | ||
|
||
vector<int> parent, set_size; | ||
|
||
int find_set(int v){ | ||
if(v == parent[v]) return v; | ||
|
||
return parent[v] = find_set(parent[v]); | ||
} | ||
|
||
void union_sets(int a, int b){ | ||
a = find_set(a); | ||
b = find_set(b); | ||
if(a != b){ | ||
if(set_size[a] < set_size[b]) | ||
swap(a, b); | ||
parent[b] = a; | ||
set_size[a] += set_size[b]; | ||
} | ||
} | ||
|
||
bool same_set(int a, int b){ | ||
a = find_set(a); | ||
b = find_set(b); | ||
|
||
return a == b; | ||
} | ||
|
||
// in this problem we need to know how many similar groups are there | ||
// we can do that by brute force and check each pair of strings if they are similar or not | ||
// and if they are similar we can merge them in the same group which will help us to know the number of groups at the end | ||
|
||
|
||
int numSimilarGroups(vector<string>& strs) { | ||
// n: number of strings | ||
int n = strs.size(); | ||
// parent: parent of each string | ||
parent.assign(n, 0); | ||
// set_size: size of each set | ||
set_size.assign(n, 1); | ||
|
||
// initially each string is in its own set (group) and its parent is itself | ||
for(int i = 0; i < n; i++) | ||
parent[i] = i; | ||
|
||
|
||
// we can check each pair of strings if they are similar or not and merge them in the same group if they are similar | ||
for(int i = 0; i < n; i++){ | ||
for(int j = i + 1; j < n; j++){ | ||
// if they are not in the same group then we check if they are similar or not | ||
if(!same_set(i, j)){ | ||
// cnt: number of different characters between the two strings | ||
int cnt = 0; | ||
// loop over the two strings and count the number of different characters and add a condition to break the loop if the number of different characters is more than 2 | ||
// because if the number of different characters is more than 2 then the two strings are not similar and we don't need to check the rest of the characters | ||
for(int k = 0; k < strs[i].size() && cnt <= 2; k++) | ||
cnt += (strs[i][k] != strs[j][k]); | ||
|
||
// if the number of different characters is 0 or 2 then the two strings are similar and we merge them in the same group | ||
if(cnt == 0 || cnt == 2) union_sets(i, j); | ||
} | ||
} | ||
} | ||
|
||
// st: set of parents of all strings | ||
set<int> st; | ||
|
||
// loop over all strings and insert their parents in the set | ||
for(int i = 0; i < n ; i++) | ||
st.insert(find_set(i)); | ||
|
||
// return the size of the set which is the number of groups | ||
return st.size(); | ||
} | ||
}; |
57 changes: 57 additions & 0 deletions
57
04- April/28- Similar String Groups/28- Similar String Groups (Osama Ayman).java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Author: Osama Ayman | ||
// Time: O(n*n*m) | ||
// Space: O(n*n) | ||
class Solution { | ||
public int numSimilarGroups(String[] strs) { | ||
// adjacency map to represent the graph | ||
Map<Integer, List<Integer>> adj = new HashMap<>(); | ||
int n = strs.length; | ||
// adding edges if they are similar | ||
for(int i=0; i<n; i++){ | ||
for(int j=i+1; j<n; j++){ | ||
if(isSimilar(strs[i], strs[j])){ | ||
// adding undirected edge (bi-directional) | ||
adj.computeIfAbsent(i, k -> new ArrayList<>()).add(j); | ||
adj.computeIfAbsent(j, k -> new ArrayList<>()).add(i); | ||
} | ||
} | ||
} | ||
int connectedComponents = 0; | ||
Set<Integer> vis = new HashSet<>(); | ||
for(int i=0; i<n; i++){ | ||
if(!vis.contains(i)){ | ||
connectedComponents++; | ||
dfs(i, adj, vis); | ||
} | ||
} | ||
return connectedComponents; | ||
} | ||
private void dfs(int node, Map<Integer, List<Integer>> adj, Set<Integer> vis){ | ||
if(vis.contains(node) || !adj.containsKey(node)) return; | ||
vis.add(node); | ||
for(int neigh: adj.get(node)){ | ||
dfs(neigh, adj, vis); | ||
} | ||
} | ||
private boolean isSimilar(String s1, String s2){ | ||
char c1='.',c2='.'; | ||
|
||
for(int i=0; i<s1.length(); i++){ | ||
// if they are equal, continue | ||
if(s1.charAt(i) == s2.charAt(i)) continue; | ||
// if they are not equal and c1 is not set, set c1 and c2 | ||
if(c1=='.'){ | ||
c1=s1.charAt(i); | ||
c2=s2.charAt(i); | ||
} | ||
// if they are equal and c1 and c2 are set, but they are not equal to the | ||
//char of the other string, return false | ||
else if(!(s1.charAt(i) == c2 && s2.charAt(i) == c1) ){ | ||
return false; | ||
} | ||
|
||
|
||
} | ||
return true; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
...ersable/30- Remove Max Number of Edges to Keep Graph Fully Traversable (Ahmed Hossam).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Author: Ahmed Hossam | ||
|
||
// Define a generic disjoint-set union data structure with an optional base node | ||
// parameter for 1-based indexing, and a template parameter for data type T. | ||
template <typename T = int, int Base = 1> | ||
struct DSU { | ||
// The parent vector stores the parent of each node, and the Gsize vector | ||
// stores the size of each disjoint set. | ||
vector<T> parent, Gsize; | ||
|
||
// Constructor initializes the parent and Gsize vectors for all nodes. | ||
DSU(int MaxNodes) { | ||
parent = Gsize = vector<T>(MaxNodes + 5); | ||
for (int i = Base; i <= MaxNodes; i++) | ||
parent[i] = i, Gsize[i] = 1; | ||
} | ||
|
||
// Recursive function to find the leader of the disjoint set that the node | ||
// belongs to, and updates the parent of all visited nodes to the leader. | ||
T find_leader(int node) { | ||
return parent[node] = (parent[node] == node ? node : find_leader(parent[node])); | ||
} | ||
|
||
// Returns true if the two nodes belong to the same disjoint set. | ||
bool is_same_sets(int u, int v) { | ||
return find_leader(u) == find_leader(v); | ||
} | ||
|
||
// Merges the disjoint sets containing the two nodes u and v. | ||
void union_sets(int u, int v) { | ||
int leader_u = find_leader(u), leader_v = find_leader(v); | ||
if (leader_u == leader_v) return; | ||
if (Gsize[leader_u] < Gsize[leader_v]) swap(leader_u, leader_v); | ||
Gsize[leader_u] += Gsize[leader_v], parent[leader_v] = leader_u; | ||
} | ||
|
||
// Returns the size of the disjoint set that the node belongs to. | ||
int get_size(int u) { | ||
return Gsize[find_leader(u)]; | ||
} | ||
}; | ||
|
||
class Solution { | ||
public: | ||
int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) { | ||
// Variable to store the number of edges removed. | ||
int removed_edges = 0; | ||
// Create two disjoint-set union objects, one for Alice and one for Bob. | ||
DSU<int> alice(n), bob(n); | ||
// Sort edges in decreasing order of type so that type 3 edges are | ||
// processed last. | ||
sort(edges.rbegin(), edges.rend()); | ||
// Loop through each edge in the sorted list. | ||
for (auto& edge : edges) { | ||
int t = edge[0], u = edge[1], v = edge[2]; | ||
// Process the edge based on its type. | ||
if (t == 1) { | ||
if (alice.is_same_sets(u, v)) removed_edges++; | ||
else alice.union_sets(u, v); | ||
} else if (t == 2) { | ||
if (bob.is_same_sets(u, v)) removed_edges++; | ||
else bob.union_sets(u, v); | ||
} else { | ||
if (alice.is_same_sets(u, v) && bob.is_same_sets(u, v)) removed_edges++; | ||
else alice.union_sets(u, v), bob.union_sets(u, v); | ||
} | ||
} | ||
// Check if all nodes belong to the same disjoint set for both Alice and | ||
// Bob. If not, return -1 as it is impossible to remove enough edges to | ||
// create a spanning tree for both players. | ||
if (alice.get_size(1) != n || bob.get_size(1) != n) | ||
return -1; | ||
// Return the number of edges removed. | ||
return removed_edges; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters