๐ 1. ๋ฌธ์ ์ค๋ช
๐ก 2. ์ ๊ทผ๋ฐฉ์
์ด ๋ฌธ์ ๋ ๋๋ฌด ์ด๋ ค์์ ์ค์ค๋ก ํ๊ธฐ ํ๋ค์ด์ ๊ฒ์์ ๋์์ ๋ฐ์.
์ฃผ์ด์ง ๋ฌธ์ ๋ ๊ทธ๋ํ ์ด๋ก ์ ์ต์ ์ ์ฅ ํธ๋ฆฌ(MST, Minimum Spanning Tree) ๋ฌธ์ ์ด๋ค.
์ด ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํด ํ์ํ ์ ์ ์ง์
- Union-Find(์ ๋์จ ํ์ธ๋) ์๋ฃ๊ตฌ์กฐ
- Kruskal's Algorithm (ํฌ๋ฃจ์ค์นผ) ์๊ณ ๋ฆฌ์ฆ
Kruskal's Algorithm (ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ)
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ ์์ ๋งํ ์ต์์ ์ฅํธ๋ฆฌ(MST)๋ฅผ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ๋ฌธ์ ์ ๋ถ๋ฅ ๋ต๊ฒ greedy์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ฒฐ์ ์ ์๊ฐ๋ง๋ค ์ต์ ์ ๊ฒฐ์ ์ ํจ์ผ๋ก์ ์ต์ข
์ ์ธ ๋ต์ ๊ตฌํ๋ ๋ฐฉ์์ผ๋ก ๋ชจ๋ ์ ์ ์ ์ต์ ๋น์ฉ์ผ๋ก ์ฐ๊ฒฐํ ์ ์๊ฒ ํด์ค๋ค.
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ์ ๋ชจ๋ ๊ฐ์ ์ ๊ฐ์ค์น ๊ธฐ์ค(์ฌ๊ธฐ์๋ ๋ค๋ฆฌ ๊ฐ์ค ๋น์ฉ)์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ๊ฐ์ ๋ค์ ์์๋๋ก ๋ชจ๋ ์ ์ ์ด ์ฐ๊ฒฐ๋ ๋ ๊น์ง ์ฐ๊ฒฐํ๋ ๊ฒ์ด๋ค. ์ฐ๊ฒฐ์ Union-find ์๋ฃ๊ตฌ์กฐ์ ์ด์ฉํ์ฌ ๊ตฌํํ ์ ์๊ณ , ์ฌ์ดํด์ด ํ์ฑ๋์ง ์๋ ๋ชจ๋ ์ ์ ์ ๋ณํฉํด ์ฃผ๋ฉด ๋๋ค.
Union-Find(์ ๋์จ ํ์ธ๋) ์ ๋ฆฌ์๋ ๋ธ๋ก๊ทธ
์ฝ๋ ํ๋ฆ
1. costs ๋ฐฐ์ด์ ๋ค๋ฆฌ ๊ฐ์ค ๋น์ฉ์ด ๋ฎ์ ์์๋ถํฐ ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
2. ์ ๋์จ ํ์ธ๋ ์ด๊ธฐํ
- ๊ฐ ์ฌ์ ์ฒ์์๋ ๋
๋ฆฝ์ ์ด๋ฏ๋ก ์๊ธฐ ์์ ์ ๋ถ๋ชจ๋ก ๊ฐ์ง๋ค. -> parent ๋ฐฐ์ด
3. ์ ๋ ฌ๋ ๋ค๋ฆฌ ๋ฆฌ์คํธ๋ฅผ ์ํํ๋ฉฐ, Union-Find๋ก ์ฐ๊ฒฐ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ค.
- ๋น์ฉ์ด ๋ฎ์ ๋ค๋ฆฌ๋ถํฐ ์ ํํ๊ณ ๋ ์ฌ์ด ๋ค๋ฅธ ์งํฉ์ ์๋ค๋ฉด ์ฌ์ ์ฐ๊ฒฐํ๋ค.
- ๋ชจ๋ ์ฌ์ด ๋ค ์ฐ๊ฒฐ๋ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
4. ๋ชจ๋ ์ฌ์ด ์ฐ๊ฒฐ๋์์ ๋ ์ ํํ ๋ค๋ฆฌ ๋น์ฉ์ ๋ชจ๋ ๋ํ ๊ฐ์ ๋ฐํํ๋ค.
๋ฌธ์ ์์ ์ฃผ์ด์ง ์์๋ฐฐ์ด costs ์ ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ์ฌ
์ฝ๋์ ํ๋ฆ๋๋ก ์๊ฐํ ํด ๋ณด์๋ค.
costs ๋ฐฐ์ด
[[0, 1, 1], [0, 2, 2], [1, 2, 5], [1, 3, 1], [2, 3, 8]]
costs[i][2] ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
[0, 1, 1]
[1, 3, 1]
[0, 2, 2]
[1, 2, 5]
[2, 3, 8]
์ฒซ ๋ฒ์งธ ๋ฐ๋ณต
costs์์ [0, 1, 1] ๊ฐ์ ๊บผ๋ธ๋ค.
0์ ๋ถ๋ชจ๋ 0
1์ ๋ถ๋ชจ๋ 1
๋ถ๋ชจ๊ฐ ๊ฒน์น์ง ์์ -> ๋ค๋ฆฌ๋ฅผ ๊ฑด์คํ๋ค.
union์ฐ์ฐ์ผ๋ก ์ฌ1์ ์ฌ0 ์งํฉ์ ํตํฉํ๋ค.
<ํ์ฌ ์ํ>
๊ทธ๋ฃน 0 : [์ฌ0, ์ฌ1]
๊ทธ๋ฃน 2 : [์ฌ2]
๊ทธ๋ฃน 3 : [์ฌ3]
๋ ๋ฒ์งธ ๋ฐ๋ณต
costs์์ ๊ฐ [1, 3, 1]์ ๊บผ๋ธ๋ค.
1์ ๋ถ๋ชจ๋ 0
3์ ๋ถ๋ชจ๋ 3
๋ถ๋ชจ๊ฐ ๊ฒน์น์ง ์์ -> ๋ค๋ฆฌ๋ฅผ ๊ฑด์คํ๋ค.
union์ฐ์ฐ์ผ๋ก ์ฌ3์ ์ฌ1 ์งํฉ์ ํตํฉํ๋ค.
<ํ์ฌ ์ํ>
๊ทธ๋ฃน 0 : [์ฌ0, ์ฌ1, ์ฌ3]
๊ทธ๋ฃน 2 : [์ฌ2]
์ธ ๋ฒ์งธ ๋ฐ๋ณต
costs์์ ๊ฐ [0, 2, 2]์ ๊บผ๋ธ๋ค.
0์ ๋ถ๋ชจ๋ 0
2์ ๋ถ๋ชจ๋ 2
๋ถ๋ชจ๊ฐ ๊ฒน์น์ง ์์ -> ๋ค๋ฆฌ๋ฅผ ๊ฑด์คํ๋ค.
union์ฐ์ฐ์ผ๋ก ์ฌ2์ ์ฌ0 ์งํฉ์ ํตํฉํ๋ค.
<ํ์ฌ ์ํ>
๊ทธ๋ฃน 0 : [์ฌ0, ์ฌ1, ์ฌ2, ์ฌ3]
๋ค ๋ฒ์งธ ๋ฐ๋ณต
costs์์ ๊ฐ [1, 2, 5]์ ๊บผ๋ธ๋ค.
1์ ๋ถ๋ชจ๋ 0
2์ ๋ถ๋ชจ๋ 0์ด๋ค.
0, 1, 2๋ ํ๋์ ์ฌ์ดํด์ ๋๋ค.
๋ฐ๋ผ์ ๋ค๋ฆฌ ๊ฑด์ค์์ ์ ์ธํ๋ค.
๋ค์ฏ ๋ฒ์งธ ๋ฐ๋ณต
costs์์ ๊ฐ [2, 3, 8]์ ๊บผ๋ธ๋ค.
2์ ๋ถ๋ชจ๋ 0
3์ ๋ถ๋ชจ๋ 0์ด๋ค.
๊ทธ๋ํ์์ 0, 1, 2, 3๋ ํ๋์ ์ฌ์ดํด์ ๋๋ค.
๋ฐ๋ผ์ ๋ค๋ฆฌ ๊ฑด์ค์์ ์ ์ธํ๋ค.
๋ฐ๋ผ์ ๋ฐ๋ณต๋ฌธ์ ๋ชจ๋ ๋๊ณ ๋ ํ์ ์ต์ข
์ ์ผ๋ก ๊ฑด์ค๋ ๋ค๋ฆฌ๋ 3๊ฐ์ด๋ค.
๋ํ ๋ฌธ์ ์์ ๋ค๋ฆฌ ๊ฑด์ค์ ๋๋ ์ต์ ๋น์ฉ์ return ํ๋ผ๊ณ ํ์ผ๋ฏ๋ก 1 + 1 + 2 = 4๊ฐ ๋๋ค.
โญ 3. ์ ๋ต์ฝ๋
import java.util.*;
class Solution {
// ๋ถ๋ชจ๋ฅผ ์ฐพ๋ ํจ์ (Find ์ฐ์ฐ)
// ๊ฒฝ๋ก ์์ถ
public int find(int[] parent, int node) {
if (parent[node] == node) return node; // ์์ ์ด ๋ถ๋ชจ๋ผ๋ฉด ๊ทธ๋๋ก ๋ฐํ
return find(parent, parent[node]); // ๋ถ๋ชจ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ ์ต์์ ๋ถ๋ชจ ์ฐพ๊ธฐ
}
// ๋ ๋
ธ๋๋ฅผ ๊ฐ์ ์งํฉ์ผ๋ก ๋ฌถ๋ ํจ์ (Union ์ฐ์ฐ)
public void union(int[] parent, int node1, int node2) {
int p1 = find(parent, node1); // ์ฒซ ๋ฒ์งธ ๋
ธ๋์ ๋ถ๋ชจ ์ฐพ๊ธฐ
int p2 = find(parent, node2); // ๋ ๋ฒ์งธ ๋
ธ๋์ ๋ถ๋ชจ ์ฐพ๊ธฐ
// ๋ ์งํฉ์ ๋ณํฉ (๋ถ๋ชจ๊ฐ ์์ ์ชฝ์ ์ต์์ ๋ถ๋ชจ๋ก ํจ)
if (p1 < p2) {
parent[p2] = p1;
} else {
parent[p1] = p2;
}
}
public int solution(int n, int[][] costs) {
int answer = 0; // ๋ชจ๋ ์ฌ์ ์ฐ๊ฒฐํ๋ ๋ฐ ํ์ํ ์ต์ ๋น์ฉ ๋์ ํ๋ ๋ณ์
int[] parent = new int[n]; // ์ ๋์จ ํ์ธ๋ ๋ฐฐ์ด (๊ฐ ๋
ธ๋์ ๋ถ๋ชจ ์ ์ฅ)
// ์ด๊ธฐํ: ๊ฐ ๋
ธ๋๋ ์๊ธฐ ์์ ์ด ๋ถ๋ชจ๋ก ์์ํจ
for (int i = 0; i < parent.length; i++)
parent[i] = i;
// costs ๋ฐฐ์ด์ ๋น์ฉ(costs[i][2]) ๋ค๋ฆฌ๊ฑด์ค๋น์ฉ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
Arrays.sort(costs, new Comparator<int[]>() {
@Override
public int compare(int[] cost1, int[] cost2) {
return cost1[2] - cost2[2]; // ๋น์ฉ ๊ธฐ์ค ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
}
});
// ๋น์ฉ์ด ๋ฎ์ ๋ค๋ฆฌ๋ถํฐ ์ํํ๋ฉฐ ์ฐ๊ฒฐ ์์
์งํ
for (int i = 0; i < costs.length; i++) {
// ๋ ์ฌ์ด ์ด๋ฏธ ๊ฐ์ ์งํฉ์ ์ํด ์์ง ์๋ค๋ฉด ์ฐ๊ฒฐ
if (find(parent, costs[i][0]) != find(parent, costs[i][1])) {
answer += costs[i][2]; // ๋ค๋ฆฌ ๋น์ฉ์ ์ถ๊ฐ
union(parent, costs[i][0], costs[i][1]); // ๋ ์ฌ์ ๊ฐ์ ์งํฉ์ผ๋ก ๋ณํฉ
}
}
return answer; // ์ต์ ๋น์ฉ ๋ฐํ
}
}
๐๐ป ์ข์์ ๊ฐ์ฅ ๋ง์ด ๋ฐ์ ์ฝ๋
๋๋ค์์ผ๋ก ํํํ ์ฝ๋
import java.util.Arrays;
class Solution
{
public int solution(int n, int[][] costs)
{
int sum = 0;
int[] island = new int[n];
for(int i = 0; i < n; i++)
island[i] = i;
Arrays.sort(costs, (a, b) -> Integer.compare(a[2], b[2]));
for(int i = 0; i < costs.length; i++)
{
if(find(island, costs[i][0]) != find(island, costs[i][1]))
{
unite(island, costs[i][0], costs[i][1]);
sum += costs[i][2];
}
}
return sum;
}
private int find(int[] island, int x)
{
if(island[x]== x)
return x;
return find(island, island[x]);
}
private void unite(int[] island, int x, int y)
{
int a = find(island, x);
int b = find(island, y);
island[a] = b;
}
}
๐ฆ 4. ๊ฐ์ ์ ํ ๋ฌธ์
'Algorithm > Programmers_Best' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ํ๋ก๊ทธ๋๋จธ์ค] (Java) ์์ (๊ทธ๋ํ) ๋ฌธ์ ํ์ด (10) | 2025.01.28 |
---|---|
[ํ๋ก๊ทธ๋๋จธ์ค] (Java) N์ผ๋ก ํํ (๋์ ๊ณํ๋ฒ/Dynamic Programming) (12) | 2025.01.20 |
[ํ๋ก๊ทธ๋๋จธ์ค] (Java) ๋จ์์นด๋ฉ๋ผ (๊ทธ๋ฆฌ๋/Greedy) (12) | 2025.01.19 |
[ํ๋ก๊ทธ๋๋จธ์ค] (Java) ๊ตฌ๋ช ๋ณดํธ (๊ทธ๋ฆฌ๋/Greedy) (12) | 2025.01.15 |
[ํ๋ก๊ทธ๋๋จธ์ค] (Java) ํฐ ์ ๋ง๋ค๊ธฐ (๊ทธ๋ฆฌ๋/Greedy) (4) | 2025.01.14 |