첫번째 풀이 (실패)
- set에 1부터 n까지 아파트를 정리한다
- stations를 순회하면 영향을 받는 아파트들을 set에서 지운다
- set을 배열로 변환하여 순회하면서 연속적인 숫자가 아닌 부분 (즉 2번에서 지운 구간에 의해 나눠진 구간들)을 만날떄마다 range의 갯수로 나눠 기지국 갯수를 구한다.
function solution(n, stations, w) {
var answer = 0;
const numArr = Array.from({length: n},(_, i) => i+1);
const set = new Set(numArr);
for (const station of stations) {
set.delete(station);
for(let i = 1; i <= w; i++) {
set.delete(station+i);
set.delete(station-i);
}
}
const arr = [...set];
let left = 0;
const range = w *2+1;
for (let i = left; i < arr.length; i++) {
while(arr[i+1] - arr[i] !== 1) {
const count = i-left+1;
answer += Math.ceil(count / range);
left = i+1;
break;
}
}
return answer;
}
하지만 아파트 갯수는 2억 이하 자연수이므로 for O(n)은 효율성 테스트를 실패했다.
두번째 풀이 (성공)
문제의 핵심은
- 아파트 갯수는 2억 이하 자연수이므로 O(logN)이나 O(1) 이여야 한다
- station은 오름차순이다
- stations을 순회하며 각 station 전후로 무영향 아파트의 갯수를 구한다
- 무영향 아파트의 갯수를 사용하여 기지국 갯수를 구한다 Math.ceil(아파트갯수 / 전달범위갯수)
- 전달 범위 갯수는 2w+1이다 (w+1+w)
- stations 순회가 끝난 뒤 남은 아파트가 있으면 2번 계산식으로 기지국 갯수를 구해 더한다.
찾은 반례
stations순회 끝내고 마지막 하나만 남았을 떄
13 [3, 7, 11] 1 답: 4
function solution(n, stations, w) {
var answer = 0;
let curr = 1; // 현재위치
const rangeWidth = 2*w+1; // 전달범위길이 = w개 + 중심1개 + w개
let affectedRange; // [영향을 받는 범위의 시작, 끝]
// station전후로 영향이 없는 구역의 갯수를 구한 뒤 필요한 기지국 갯수를 더한다.
for (const station of stations) {
if (station === 1){
affectedRange = [1, 1+w]; // 기지국이 첫 말단일 때 범위
} else if (station === n) {
affectedRange = [n-w, n]; // 끝 말단일때의 범위
} else {
affectedRange = [station-w, station+w]; // 그 외 범위 만약 최쇠최대를 넘어가면 [Math.max(station-w, 1), Math.min(station+w, n)]
}
const count = affectedRange[0] - curr; // 영향이 없는 구간의 아파트 갯수
answer += Math.ceil(count / rangeWidth); // 구간 안에 필요한 최소 기지국 갯수 추가
curr = affectedRange[1]+1; // 다음 무영향 구간 시작점
}
// station을 다 통과한 뒤 남은 아파트가 있을시
if (curr <= n) {
const count = n - curr+1; // +1!!! 남은 아파트 갯수
answer += Math.ceil(count /rangeWidth);
curr = n+1;
}
return answer;
}
'알고리즘' 카테고리의 다른 글
[프로그래머스 LV2] 연속 부분 수열 합의 개수 JS (0) | 2023.11.03 |
---|---|
[다익스트라 레벨3] 부대복귀 (0) | 2023.11.03 |
[다익스트라] 배달 (0) | 2023.11.01 |
[two pointer] 릿코드 3Sum (medium) (0) | 2023.10.30 |
[two pointer] 릿코드 27. Remove Element (0) | 2023.10.22 |