| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- Stack
- 2018 KAKAO BLIND RECRUITMENT
- cpp
- 이분탐색
- 동적계획법
- 통신 인터페이스
- level2
- 컴퓨터 비전
- 다이나믹 프로그래밍
- dfs
- c++
- BFS
- 임베디드
- dp
- 코틀린
- 누적합
- JavaScript
- 컴퓨터비전
- java
- level3
- 다이나믹프로그래밍
- lv2
- 구현
- C
- 프로그래머스
- kotlin
- 우선순위큐
- 자바
- 백준
- 그리디
Archives
- Today
- Total
코드를 느껴바라
Lv.3 등대 [JAVA] 본문
문제 링크
성공 여부(걸린 시간): 실패(44분 48초)
아이디어
처음에 다양한 방법에 대해서 생각해봤다. ❌
- 브루트포스로 등대의 불 켜짐을 전부 탐색 -> X 10만개임 2^100000
- 리프노드가 있는 경우는 전부 켜주기 ❌
-> 왜냐면 리프노드가 있는 노드라면 무조건 리프노드가 달린 노드에 불이 켜져야함
-> 연결된 간선이 하나인 리프노드를 기억해두고 해당 리프노드가 연결된 노드를 set에 넣고 마지막에 개수를 세어주면 된다.
-> 그러나 0-0-0-0-0-0-0 인 경우엔 3개는 켜져야 하는데 2개 밖에 안켜진다.
- 리프노드에서 출발해서(0으로) 깊이가 홀수인 노드의 개수를 세어준다. ❌
-> 그렇다면 그래프를 만들어 연결하고 리프노드에서 DFS로 탐색을 진행하며 depth가 홀수일때 hashSet에 add 해주면 된다.
-> add해주는 조건은 이렇다. depth가 홀수이면서 리프노드가 아니여야함
그래서 어떻게 한지 다른 분들의 코드를 참고해봤더니 DFS+DP였다.
내가 제일 자신없는 DFS+DP 이제 극복할때가 온 것 같다.
코드 흐름은 아래와 같다.
- 그래프 구성
graph를 인접 리스트로 초기화하고,lighthouse간선을 양방향으로 연결.
- 배열 초기화
dp[n+1][2]와visited[n+1]준비.
- DFS 시작
- 임의 루트(1)에서
DFS(1)호출.
- 임의 루트(1)에서
- DFS(u) 내부
visited[u] = true- 기본값 설정:
dp[u][0] = 0(u 끔),dp[u][1] = 1(u 켬) - 인접 정점
x순회- 이미 방문했으면 건너뜀
- 미방문이면
DFS(x)재귀 호출 - 자식 처리 후 갱신
dp[u][0] += dp[x][1]dp[u][1] += Math.min(dp[x][0], dp[x][1])
- 결과 반환
- DFS가 끝나면 루트(1)에서
Math.min(dp[1][0], dp[1][1])를 반환.
- DFS가 끝나면 루트(1)에서
풀이 코드
import java.util.*;
class Solution {
static ArrayList<ArrayList<Integer>> graph;
static boolean [] visited;
static int [][] dp;
public int solution(int n, int[][] lighthouse) {
graph = new ArrayList<>();
for(int i=0; i<=n; i++){
graph.add(new ArrayList<>());
}
for(int [] light: lighthouse){
graph.get(light[0]).add(light[1]);
graph.get(light[1]).add(light[0]);
}
dp = new int[n+1][2];
visited = new boolean[n+1];
DFS(1);
return Math.min(dp[1][0], dp[1][1]);
}
static void DFS(int node){
visited[node] = true;
dp[node][0] = 0; // 등대 꺼진 경우
dp[node][1] = 1; // 등대 켜진 경우
for(int x: graph.get(node)){
if(visited[x]){
continue;
}
DFS(x);
dp[node][0] += dp[x][1];
dp[node][1] += Math.min(dp[x][0], dp[x][1]);
}
}
//마지막엔 결국 인덱스 1에 전부 저장되게끔 설계
}반응형
'PS > 프로그래머스(Programmers)' 카테고리의 다른 글
| Lv.2 전력망을 둘로 나누기 [JAVA] (2) | 2025.08.19 |
|---|---|
| Lv.2 롤케이크 자르기 [JAVA] (4) | 2025.08.17 |
| Lv.2 미로 탈출 [JAVA] (3) | 2025.07.31 |
| Lv.2 숫자 변환하기 [JAVA] (4) | 2025.07.30 |
| Lv.2 귤 고르기 [JAVA] (4) | 2025.07.26 |
