https://school.programmers.co.kr/learn/courses/30/lessons/43162
첫 풀이
처음에 단순히 섬의 개수를 구하는 문제와 비슷하다고 생각해서 땅을 찾으면 땅을 파고들어갔는데 문제를 잘 못 이해한거 였다
function solution(n, computers) {
var answer = 0;
const direction = [
[-1, 0],
[0, 1],
[1, 0],
[0, -1],
];
function dfs(r, c) {
for (const [dx, dy] of direction) {
const nextR = r + dx;
const nextC = c + dy;
if (
nextR >= 0 &&
nextR < n &&
nextC >= 0 &&
nextC < n &&
computers[nextR][nextC] === 1
) {
computers[nextR][nextC] = 0;
dfs(nextR, nextC);
}
}
}
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (computers[i][j] === 1) {
computers[i][j] = 0; //
answer++;
dfs(i, j);
}
}
}
return answer;
}
반례
solution(4, [[1, 1, 0, 1], [1, 1, 0, 0], [0, 0, 1, 1], [1, 0, 1, 1]])
answer=1
이차배열상의 네트워크를 구하는게 아니였다.
최종풀이 (dfs)
현재와 연결된 곳을 먼저 방문
1. n개의 지역을 방문한 적있는지 체크하는 array를 만들고
2. 방문한 적이 없는 곳을 방문할때마다 isVisited[i] = true하고 answer++한뒤 연결된 곳을 다 방문한다
3. 연결됬지만 방문한적 없는 곳을 찾으면 2번을 반복한다
function solution(n, computers) {
var answer = 0;
const isVisited = new Array(n).fill(false);
function dfs(curr) {
for (let i = 0; i < n; i++) {
// 자기자신 아닌, curr과 연결되어있고, 방문한적 없는곳을 방문한다
if (i !== curr && computers[curr][i] === 1 && !isVisited[i]) {
isVisited[i] = true;
dfs(i);
}
}
}
for (let i = 0; i < n; i++) {
// 방문한 적 없는 곳
if (!isVisited[i]) {
isVisited[i] = true;
answer++;
dfs(i); // 연결된 곳 모두 방문하기
}
}
return answer;
}
최종풀이 (union find)
하나의 네트워크 안에서 가장 작은 노드의 수를 부모라고하면, 부모의 갯수 = 네트워크 갯수
주의
find 함수 안 에서 현재 노드가 최상단 부모가 아닌 경우
parents[n] = find(parents[n])
function solution(n, computers) {
const parents = Array.from({length: n}, (_, i) => i);
function find(n) {
if (parents[n] === n) return n;
parents[n] = find(parents[n]); // !
return parents[n];
}
function union(a, b) {
const aParent = find(a);
const bParent = find(b);
if (aParent < bParent) {
parents.forEach((parent, i) => {
if (parent === bParent) {
parents[i] = aParent;
}
})
} else {
parents.forEach((parent, i) => {
if (parent === aParent) {
parents[i] = bParent;
}
})
}
}
for (let r = 0; r < n; ++r) {
// 대각선 기준으로 대칭이므로 c = r+1부터 확인하여 반복을 줄인다 [0, 0] 나 [0,1] = [1,0]
for (let c = r+1; c < n; ++c) {
// 아직 연결이 안 됐을 때
if (computers[r][c] === 1 && find(r) !== find(c)) {
union(r, c);
}
}
}
return new Set(parents).size;
}
'알고리즘' 카테고리의 다른 글
[크루스칼] 섬 연결하기 (0) | 2023.09.25 |
---|---|
MST 최소비용신장트리, Union find 개념과 JS코드 (0) | 2023.09.25 |
색종이 만들기 (dfs) (0) | 2023.09.23 |
[그리디] 체육복 (0) | 2023.09.20 |
[DP] N으로 표현 (0) | 2023.09.03 |