https://school.programmers.co.kr/learn/courses/30/lessons/12979
현재 4g 기지국이 설치되어있다.
이걸 5g 기지국으로 변경하면 전체 아파트에 전파의 범위가 도달하지 못할수도 있다.
5g기지국을 최소로 설치하면서 전체 아파트에 전파를 도달하려면 기지국을 몇개 설치해야하는가?
- n: 11
- stations: [4, 11]
- w: 1
아래 예시는 위의 입력이 있을경우를 설명한다.
처음에는 n개의 배열을 만들어서 station의 범위만 1을 초기화 하고 나머지는 0으로 초기화후
아래 두가지 경우에 result를 1 늘렸다
그렇게 짠 기존 방식은 아래와 같다.
const solution = (n, stations, w) => {
const apts = Array(n + 1).fill(0);
const range = w * 2 + 1;
let cnt = 0;
let rst = 0;
let now = 0;
stations.forEach(station => {
for (let i = station - w; i <= station + w; i++) {
apts[i] = 1;
}
});
for (let i = 1; i <= n; i++) {
const apt = apts[i];
if (apt === 0) {
now = 0;
cnt++;
if (cnt === range) {
cnt = 0;
rst++;
}
}
if (apt === 1 && now === 0) {
if (cnt > 0) rst++;
now = 1;
cnt = 0;
}
}
if (cnt > 0) rst++;
return rst;
};
하지만 이 방법에는 치명적인 단점이 존재한다.
n의 범위가 최대 2억개라서 무조건 시간초과가 난다는거다.
그래서 다른 방법을 찾아야 하는데 생각하는 방식을 조금 바꿔봤다.
원래 n을 끝까지 돌면서 기존 기지국에 더해서 새로운 기지국을 박는 방식으로 생각을 했는데
그냥 station만 돌면서 기존 범위를 갱신해주며 기지국이 닿지 않는 범위만 기지국을 더해주는 방식으로 바꿔줬다.
예를들어 아래처럼 맨 위의 예제가 입력으로 주어지면
- n: 11
- stations: [4, 11]
- w: 1
이를 코드로 표현하면 아래와 같다.
const solution = (n, stations, w) => {
const range = w * 2 + 1;
let result = 0;
let lastCoverage = 1;
stations.forEach(now => {
const right = now - w - 1;
const coverRange = right - lastCoverage + 1;
const needStationNum = Math.ceil(coverRange / range);
result += needStationNum;
lastCoverage = now + w + 1;
});
// if문이 없어도 결국 남은 범위가 없으면 0이 추가돼서
// if문은 없어도 무방하긴 하다.
if (lastCoverage <= n) {
const coverRange = n - lastCoverage + 1;
const needStationNum = Math.ceil(coverRange / range);
result += needStationNum;
}
return result;
};