[문제풀이] 징검다리

업데이트:

문제 링크 : 징검다리

풀이 시간 : 30분

1. 문제 풀이

n개의 바위를 제거하여 바위 사이의 거리 중 가장 짧은 거리 중 최대 거리를 찾는 문제

바위의 수가 50000개 이하여서 완전 탐색으로는 안된다고 판단

이진 탐색으로 가장 짧은 거리 중 최대 거리를 설정하여 가능 여부를 확인

1) 바위들의 위치 정렬

2) 이진 탐색으로 mid 값 결정

3) 전 바위와의 거리를 이용하여 mid와 비교

3-1) mid이 클 경우, mid가 최소가 아니므로 현재 바위 제거 후 전 바위 유지

3-2) 작을 경우, 전 바위 위치를 현재 바위로 변경

4) mid의 가능 여부 확인

4-1) 제거한 바위 수가 n보다 작거나 같을 경우, start = mid

4-2) 클 경우, end = mid-1

2. 소스 코드

    public int solution(int distance, int[] rocks, int n) {
		// 바위들의 위치 정렬(오름차순)
		Arrays.sort(rocks);
		int[] arr = new int[rocks.length + 2];
		// 시작 바위
		arr[0] = 0;
		for (int i = 0; i < rocks.length; i++) {
			arr[i + 1] = rocks[i];
		}
		// 끝 바위
		arr[rocks.length + 1] = distance;
		int start = 1;
		int end = distance;
		int mid;
		// 바위 사이의 거리의 최소값 중 가장 큰 값 찾기
		// 이진 탐색으로 검색
		while (start < end) {
			// mid 값으로 가능한 거리인지 판단
			mid = (start + end) / 2+1;
			int prev = 0;
			// 바위 제거 횟수
			int count = 0;
			boolean check = true;
			for (int i = 1; i < arr.length; i++) {
				// 현재 바위와 전 바위의 거리
				int temp = arr[i] - prev;
				// mid 값보다 작으면 mid 값이 최소가 아니므로 제거
				if (mid > temp) {
					count++;
					// 제거된 바위가 제거 할 수 있는 수보다 크면 종료
					if (count > n) {
						check = false;
						break;
					}
				} else {
					// 전 바위 변경
					prev = arr[i];
				}
			}
			if (check) {
				start = mid;
			} else {
				end = mid - 1;
			}
		}
		return start;
	}

3. 후기

Level 4 문제치고는 쉬운 문제였다.

문제 옆에 이분 탐색이라는 말이 써있기 때문에 빨리 해결하였다.

상반기 코딩 테스트에서 이분 탐색을 사용하는 문제가 종종 보였던거 같은데 연습으로 풀기 좋은 문제였다.