👀 문제
https://programmers.co.kr/learn/courses/30/lessons/1829
👊 도전
1. 설계
- DFS로 배열을 순회하며 영역 개수를 센다.
- picture 크기와 같은 int형 visit 배열을 생성하고, 위치를 방문했을 때 picture값을 넣어 중복 탐색을 방지한다.
- 영역별로 체크가 끝날 때 마다 max에 영역 개수의 최대값을 저장한다.
2. 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.util.*;
/**
*
* @author HEESOO
*
*/
class Solution {
int[][] visit; // 방문 체크 배열
ArrayList<Integer> list; // 영역별 넓이 저장
int cnt, max; // 탐색하고 있는 영역의 넓이, 전체 영역 넓이 중 최대값
int[] dotX={0,1,0,-1};
int[] dotY={1,0,-1,0};
public int[] solution(int m, int n, int[][] picture) {
int[] answer = new int[2];
visit=new int[m][n];
list=new ArrayList<>();
max=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
// 색깔이 있고 방문하지 않는 곳이면 해당 영역 찾기
if(picture[i][j]!=0 && visit[i][j]==0){
cnt=1;
dfs(i, j, m, n, picture);
// 영역 탐색 완료 후 max, list에 값 저장
max=Math.max(max, cnt);
list.add(cnt);
}
}
}
answer[0] = list.size();
answer[1] = max;
return answer;
}
public void dfs(int x, int y, int m, int n, int[][] picture){
visit[x][y]=picture[x][y]; // 방문했음을 표시
for(int i=0;i<4;i++){ // 사방으로 갈 수 있는 좌표 계산
int xx=x+dotX[i];
int yy=y+dotY[i];
if(xx<0 || xx>=m || yy<0 || yy>=n) continue; // 범위 초과
if(visit[xx][yy]!=0) continue; // 방문한 곳이면 패스
if(picture[xx][yy]==picture[x][y]){ // 현재 탐색 영역과 색깔이 같다면
cnt++;
dfs(xx, yy, m, n, picture); // 이동
}
}
}
}
3. 결과
🤟 성공 🤟
4. 설명
- DFS를 이용한다
- 배열의 영역을 구하는 문제는 주로 DFS를 이용한다.
- picture 값 별로 같은 영역을 구해야 하므로 visit 배열을 int형으로 선언하여, 방문한 곳이면 picture 값(색깔)을 저장한다.
- dotX, dotY 배열을 통해 상하좌우로 이동할 수 있는 좌표를 저장한다.
- for문으로 상하좌우 좌표를 계산하고, 배열 범위와 방문한 곳인지를 체크한다.
- 탐색하는 영역의 색깔과 같다면(picture[i][j]), 영역이 늘어났으므로 cnt++하고 재귀 호출을 통해 그 곳으로 이동한다.
- main에서 picture을 순회하며 색깔이 있고 방문하지 않은 영역을 찾아 dfs를 호출한다
- 이중 for문을 통해 picture의 모든 원소를 탐색하지만, visit로 방문 여부를 체크하였기 때문에 같은 곳을 두 번 이상 dfs를 사용하는 경우는 없다.