문제
TRY
function solution(n, lost, reserve) {
var answer = 0;
// 학생 수 만큼 배열의 가지고 있는 유니폼 수를 1로 초기화
let hasUniform = new Array(n).fill(1);
// 잃어버린 학생은 -1 을 해줌
for (let i = 0; i < lost.length; i++) {
hasUniform[lost[i] - 1]--;
}
// 여벌이 있으면 +1 을 해줌
for (let i = 0; i < reserve.length; i++) {
hasUniform[reserve[i] - 1]++;
}
for (let i = 0; i < hasUniform.length; i++) {
// 유니폼이 없을 때 좌우 학생이 유니폼이 있을경우 빌려줌
if (hasUniform[i] === 0) {
if (hasUniform[i - 1] === 2) {
hasUniform[i]++;
hasUniform[i - 1]--;
} else if (hasUniform[i + 1] === 2) {
hasUniform[i]++;
hasUniform[i + 1]--;
}
}
// 유니폼이 1개이상 있으면 통과
if (hasUniform[i] >= 1) {
answer++;
}
}
return answer;
}
console.log(solution(5, [2, 4], [1, 3, 5]));
console.log(solution(5, [2, 4], [3]));
console.log(solution(3, [3], [1]));
console.log(solution(7, [2, 3, 4], [1, 2, 3, 6]));
학생 수 만큼 배열을 만들고 유니폼 수를 1로 초기화 했다.
잃어버린 학생은 -1을 해주고 여벌이 있으면 +1을 해주었다.
유니폼이 없을 경우 좌우에 여벌이 있는 학생을 찾고 있으면 빌려주고
그 후에 유니폼이 있으면 answer를 증가시키는 방식으로 정답을 구하였다.
아무래도 학생 수가 적으니 for문을 여러번 하더라도
이렇게 명시적으로 코딩하는 게 낫다고 판단하였다.
Refactoring
function solution(n, lost, reserve) {
// reserve의 얇은 복사본
// slice()를 쓰면 reserve가 변할 때 tmp가 변하지 않지만
// splice()를 쓰면 reserver가 변할 때 tmp가 변한다.
let tmp = reserve.slice();
for (let i in tmp) {
// 잃어 버린 학생이 여분이 있는 학생인지 확인
let key = lost.indexOf(tmp[i]);
// 여분이 없으면 여분이 있는 학생이 잃어버린 학생에게 빌려준다
if (key != -1) {
lost.splice(key, 1);
reserve.splice(reserve.indexOf(tmp[i]), 1);
}
}
for (let i of reserve) {
// 잃어버린 사람 한 칸 주위에 여분이 있는 사람이 있는지
let key = lost.includes(i - 1)
? lost.indexOf(i - 1)
: lost.indexOf(i + 1);
// 있으면 잃어버린 사람 배열에서 삭제
if (key != -1) {
lost.splice(key, 1);
}
}
return n - lost.length;
}
console.log(solution(5, [2, 4], [1, 3, 5]));
console.log(solution(5, [2, 4], [3]));
console.log(solution(3, [3], [1]));
console.log(solution(7, [2, 3, 4], [1, 2, 3, 6]));
Array.splice() 와 Array.indexOf() 를 이용하는 방법도 있다.
주의할 점은 Array.splice()는 배열 자체를 변형 시키기 때문에 for문 조건을 바꿀 수 있으므로
Array.slice()를 이용해서 tmp라는 임시배열에 얕은 복사본을 저장하고 tmp로 for문을 돌린다는 점이다.
여분이 있는 학생 수 만큼 for문을 돌면서
잃어버린 학생이 여분이 있는 학생인지 확인하고(여분이 있으면 자신의 체육복을 사용하면 되기에)
여분이 있으면 자신이 입는 형식으로 잃어버렸는데 여분이 있는 학생과
여분이 있는데 잃어버리지 않은 학생을 가린다.
그 다음 잃어버린 사람 주위에 여분이 있는 사람이 있는지 확인하고 있으면 lost 배열에서 삭제한다.
총 학생수에서 잃어버린 학생수를 빼면 참가할 수 있는 학생 수가 된다.
Best
function solution(n, lost, reserve) {
// 체육복을 잃어버렸으면서 여벌이 없는 경우
const realLost = lost.filter((element) => !reserve.includes(element));
// 여벌이 있으면서 체육복을 잃어버리지 않은 경우
let realReserve = reserve.filter((element) => !lost.includes(element));
// 학생 수(n) - 잃어버린 학생이 여벌을 못받은 경우(realLost.filter)
return (
// realLost.filter((lost) : 잃어버린 사람 중 여벌을 받을 수 없는 학생을 배열로 반환
n -
realLost.filter((lost) => {
// lend : 체육복을 빌려줄 수 있는 경우 중 첫 번째 요소
const lend = realReserve.find(
// 잃어버린 사람의 1칸 주위에 빌릴 사람이 있는 경우
(reverse) => Math.abs(reverse - lost) == 1,
);
// 빌려줄 수 있는 사람이 없으면 진짜 잃어버린 걸로 간주하고 lost를 return
if (!lend) return lost;
// 빌려 줬으면 reserve 배열에서 빌려준 사람 제외
realReserve = realReserve.filter((reverse) => reverse !== lend);
}).length
);
}
console.log(solution(5, [2, 4], [1, 3, 5]));
console.log(solution(5, [2, 4], [3]));
console.log(solution(3, [3], [1]));
console.log(solution(7, [2, 3, 4], [1, 2, 3, 6]));
방식은 위와 비슷하나 for문을 이용하지 않고 Array.filter()를 이용하여
체육복을 잃어버렸으면서 여벌이 없는 경우와 여벌이 있으면서 체육복을 잃어버리지 않은 경우를 구해주었다.
그 다음, 잃어버린 학생 중 1칸 주위에 빌려 줄 수 있는 학생이 없는 경우만 필터링 하여
총 학생수에서 잃어버린 학생수를 뺀 값을 return하는 방법이다.
(마지막 방법은 통과가 안된다고 하네요! 위에 방법들로 이용해주세요!)
'ALGORITHM > 프로그래머스 With JS' 카테고리의 다른 글
[프로그래머스] 다리를 지나는 트럭 / Javascript (0) | 2021.04.29 |
---|---|
[프로그래머스] 위장 / Javascript (0) | 2021.04.29 |
[프로그래머스] 모의고사 / Javascript (0) | 2021.04.28 |
[프로그래머스] K번째수 / Javascript (0) | 2021.04.27 |
[프로그래머스] 완주하지 못한 선수 / Javascript (0) | 2021.04.27 |
댓글