[프로그래머스] 달리기 경주 - JavaScript
2025. 1. 9. 08:53ㆍ프로그래머스 코딩테스트 연습
선수목록 players 배열을 callings 배열에서 호출된 만큼 순서를 바꿔주면 되는 간단한 문제라고 생각했다.
function solution(players, callings) {
let winnerIndex = 0;
for(let i = 0; i < callings.length; i++){
winnerIndex = players.findIndex((player) => player === callings[i])
[players[winnerIndex-1], players[winnerIndex]] = [players[winnerIndex], players[winnerIndex-1]];
}
return players;
}
처음에는 ES6 문법으로 간편하게 순서를 바꿔주려고 했으나, 프로그래머스 환경에서는 지원되지 않거나 뭔가 조건이 누락된 것인지 순서가 변경되지 않는 문제가 발생했다.
function solution(players, callings) {
let winnerIndex = 0;
for(let i = 0; i < callings.length; i++){
winnerIndex = players.findIndex((player) => player === callings[i])
let winner = players[winnerIndex];
players[winnerIndex] = players[winnerIndex-1];
players[winnerIndex-1]= winner;
}
return players;
}
순서를 바꿔줄 선수를 winner에 임시로 담아두는 방식으로 수정했더니, 코드가 정상적으로 작동하는 것을 확인할 수 잇었다. 안심하고 제출 버튼을 눌렀으나... 일부 테스트 케이스들의 통과 시간이 길어지더니, 시간초과가 뜨기 시작했다.
callings에서 선수가 호명될 때마다 인덱스를 조회하고 배열의 순서를 수정해주고 있기 때문에, 비용이 많이 드는 문제라는 것을 알 수 있었다. 시간복잡도를 고려하여 코드를 수정해야 하는 순간이었다.
players를 객체 형식으로 변형하여 관리하면, value 값을 index로 두고 +1 / -1 만 해도 순서 변경이 가능할 것 같았다. 그러나 결과값은 배열 형태여야 하기 때문에 players 배열 자체를 변형하게 될 경우, 객체를 다시 배열로 돌려놔야 한다는 문제가 있었다.
자료를 찾아보던 중, Map을 따로 선언하여 index 값만 따로 조회 및 관리하는 방법을 찾았다.
* 참고 자료: https://ji-frontdev.tistory.com/31
▶ 최종 코드
function solution(players, callings) {
// index 관리용 Map 선언
let map = new Map();
// players 배열 값을 객체 형태로 map에 넣어주기
players.forEach((player,i) => map.set(player,i))
// callings 길이 만큼 반복문 실행
for(let i=0; i<callings.length; i++){
// 호명된 선수 index 조회
const index = map.get(callings[i]);
// map에서 index 수정
map.set(callings[i], index-1);
map.set(players[index-1], index);
// players 배열 수정
[players[index], players[index-1]] = [players[index-1], players[index]];
}
return players;
}