Skip to content
Open
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,28 @@
## 考察
- 初見の問題
- Number of Islandsを一般のグラフにしたような問題
- 方針
- DFS
- BFS
- Union Find
- Step1ではDFSでやってみる
- 再帰の深さは最大で2000
- あとは実装

## Step1
- DFSで実装
- time: O(n), space: O(n)

## Step2
- BFSでも実装
- time: O(n), space: O(n)
- Union Findでも実装
- 前回Union by sizeもやったので、path compressionのみ実装
- time: O(n log n), space: O(n)
- Class Data Members の命名については以下を参照した
- https://google.github.io/styleguide/cppguide.html#Variable_Names

## Step3
- 1回目: 4m20s
- 2回目: 3m48s
- 3回目: 3m03s
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Solution {
public:
int countComponents(int n, vector<vector<int>>& edges) {
vector<vector<int>> adjacency_list(n);
vector<bool> visited(n, false);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false は書かなくても zero initialization だったか自信ありますか。

vector は色々と特殊なので、どこかで調べるといいかもしれません。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちら調べてみました。
vectorの場合、false を指定しなくても zero initialization になるんですね。
また、vector<bool> に関しては実装依存ではあるが、各要素がsingle bitに対応付けられるような特殊なメモリ最適化が行われる場合が多いと理解しました。
以下を参考にしました)
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/container/vector_bool

for (vector<int> edge : edges) {
adjacency_list[edge[0]].push_back(edge[1]);
adjacency_list[edge[1]].push_back(edge[0]);
}

int total = 0;
for (int i = 0; i < n; i++) {
if (visited[i]) continue;
visitAllConnectedNodes(i, adjacency_list, visited);
total++;
}
return total;
}

private:
void visitAllConnectedNodes(int node, vector<vector<int>>& adjacency_list, vector<bool>& visited) {
visited[node] = true;
for (int next_node : adjacency_list[node]) {
if (visited[next_node]) continue;
visitAllConnectedNodes(next_node, adjacency_list, visited);
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Solution {
public:
int countComponents(int n, vector<vector<int>>& edges) {
vector<vector<int>> adjacency_list(n);
vector<bool> visited(n, false);
for (vector<int> edge : edges) {
adjacency_list[edge[0]].push_back(edge[1]);
adjacency_list[edge[1]].push_back(edge[0]);
}

int total = 0;
for (int i = 0; i < n; i++) {
if (visited[i]) continue;
visitAllConnectedNodes(i, adjacency_list, visited);
total++;
}
return total;
}

private:
void visitAllConnectedNodes(int node, vector<vector<int>>& adjacency_list, vector<bool>& visited) {
queue<int> nodes_to_visit;
visited[node] = true;
nodes_to_visit.push(node);
while (!nodes_to_visit.empty()) {
int current_node = nodes_to_visit.front();
nodes_to_visit.pop();
for (int next_node : adjacency_list[current_node]) {
if (visited[next_node]) continue;
visited[next_node] = true;
nodes_to_visit.push(next_node);
}
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class UnionFind {
private:
vector<int> parents_;

public:
UnionFind(int n) {
parents_.resize(n, -1);
}

int find(int x) {
if (parents_[x] == -1) return x;
return parents_[x] = find(parents_[x]);
}

void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return;
parents_[x] = y;
}
};

class Solution {
public:
int countComponents(int n, vector<vector<int>>& edges) {
UnionFind uf(n);
for (vector<int> edge : edges) {
uf.unite(edge[0], edge[1]);
}

unordered_set<int> unique_groups;
for (int i = 0; i < n; i++) {
unique_groups.insert(uf.find(i));
}
return unique_groups.size();
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Solution {
public:
int countComponents(int n, vector<vector<int>>& edges) {
vector<vector<int>> adjacency_list(n);
vector<bool> visited(n, false);

for (vector<int> edge : edges) {
adjacency_list[edge[0]].push_back(edge[1]);
adjacency_list[edge[1]].push_back(edge[0]);
}

int total = 0;
for (int i = 0; i < n; i++) {
if (visited[i]) continue;
visitAllConnectedNodes(i, adjacency_list, visited);
total++;
}
return total;
}

private:
void visitAllConnectedNodes(int node, vector<vector<int>>& adjacency_list, vector<bool>& visited) {
visited[node] = true;
for (int next_node : adjacency_list[node]) {
if (visited[next_node]) continue;
visitAllConnectedNodes(next_node, adjacency_list, visited);
}
}
};