Coding Test/프로그래머스
[200421] 탐욕법(Greedy) - 섬 연결하기(level3)
csmoon1010
2020. 4. 24. 10:18
1. 문제 이해
- n개의 섬이 하나의 그룹으로 연결되도록! --> 비용이 최소가 되는 solution
- [섬1, 섬2, , cost]
2. 전략
- 비용이 최소인 경로를 우선적으로 연결
- edge의 개수는 n-1개로 고정되야 최소값을 유지할 수 있다.
- 조건 : 한 쪽만 연결되지 않은 경우만 경로에 추가
(모두 연결 - cycle 형성. edge의 개수가 n-1개를 넘어감)
(모두 연결X - 모두 연결에서 예외가 발생, 순서를 다음으로 넘긴다. / 어려웠던 예외case!!)
3. 참고했던 사항&기타사항
- 2차원 배열의 정렬
Arrays.sort(costs, Comparator.comparingInt(o1 -> o1[2])); //o1의 3번째 요소에 따라 comparingInt
for(int i= 1; i < costs.length; i++){
indexList.add(i);
}
- 모두 연결X경우의 예외 처리 --> 후보군의 index만 들어있는 배열 형성
4. 코드
import java.util.*;
class Solution {
public int solution(int n, int[][] costs) {
int answer = 0;
HashSet<Integer> check = new HashSet<>();
ArrayList<Integer> indexList = new ArrayList<>();
//2차원 배열 정렬**
Arrays.sort(costs, Comparator.comparingInt(o1 -> o1[2]));
for(int i= 1; i < costs.length; i++){
indexList.add(i);
}
//최소값으로 엣지 하나 연결
check.add(costs[0][0]); check.add(costs[0][1]);
int edge = 1;
answer += costs[0][2];
int target = 0;
//한 쪽만 연결되지 않은 경우만 엣지로 추가
while(edge < n-1 && target < costs.length){
int index = 0;
target = indexList.get(index);
int a = costs[target][0];
int b = costs[target][1];
if(check.contains(a) && check.contains(b)){ //모두 연결
indexList.remove(index);
continue;
}
while((!check.contains(a) && !check.contains(b)) ||
(check.contains(a) && check.contains(b))){ //모두 연결안됨
index++;
target = indexList.get(index);
a = costs[target][0]; b = costs[target][1];
}
indexList.remove(index);
check.add(a); check.add(b);
edge++;
answer += costs[target][2];
}
boolean[] b = new boolean[4];
int[] k = new int[4];
System.out.println(k[0] + " " + b[0] + " " + b.length);
return answer;
}
}