[알고리즘] 2차원 탐색 - 등수구하기

등수구하기

N(1<=N<=100)명의 학생의 국어점수가 입력되면 각 학생의 등수를 입력된 순서대로 출력하는 프로그램을 작성하세요.


▣ 입력설명
첫 줄에 N(3<=N<=1000)이 입력되고, 두 번째 줄에 국어점수를 의미하는 N개의 정수가 입력된다. 같은 점수가 입력될 경우 높은 등수로 동일 처리한다. 즉 가장 높은 점수가 92점인데 92점이 3명 존재하면 1등이 3명이고 그 다음 학생은 4등이 된다.
▣ 출력설명
입력된 순서대로 등수를 출력한다.
▣ 입력예제 1
5
87 89 92 100 76
▣ 출력예제 1
4 3 2 1 5


내 풀이

function solution(arr) {
  let answer = [];
  let sortedArr = [...arr].sort((a, b) => b - a);
  arr.forEach((item) => answer.push(sortedArr.indexOf(item) + 1));
  return answer;
}

사실 되게 오래 걸렸던 문제이다. 어떻게 풀면 될지 감은 잡혔었다. 내림차순으로 정렬한 뒤에 정렬된 배열에서 전달받은 배열의 아이템을 하나하나 탐색하여 그들의 인덱스가 몇 번인지 찾고 정답 배열에 푸쉬하는 식의 풀이이다. 하지만 헤맸던 부분이 어디였냐면,

let sortedArr = arr.sort((a, b) => b - a);

바로 이 부분이었다. 스프레드 연산자를 사용하지 않고 배열 그대로 sort 했더니 원하는 결과값이 나오지 않는다. 도대체 뭐가 문제일까. 당장의 sortedArr 는 콘솔에 찍어보면 스프레드 연산자를 사용하나 안하나 똑같다.

자바스크립트에서 배열을 새로운 변수에 할당하는 경우 새로운 배열은 기존 배열을 참조 한다. 따라서 새로운 배열을 변경하는 경우 원본 배열 역시 변경된다. 따라서 arr 가 정렬된 상태에서 forEach 함수를 돌리다보니 결과값이 다르게 나오는 것이다.

위에가 바로 스프레드 연산자를 사용하여 sort 하였을 때의 arr의 상태이고 아래가 배열을 새로운 변수에 그냥 할당하였을 때의 상태이다. 아래는 정렬된 상태인 것을 알 수 있다.

따라서 sort 메서드는 원본 배열을 변경하므로 원본 배열을 스프레드 연산자로 얕은 복사한 배열을 sort 하는 것이 맞다!

강사님 풀이

function solution(arr){  
  let n=arr.length;
  let answer=Array.from({length:n}, ()=>1);
  for(let i=0; i<n; i++){
    for(let j=0; j<n; j++){
      if(arr[j]>arr[i]) answer[i]++;
    }
  }             
  return answer;
}

가장 일반적인 2중 for문 풀이법이다.

좋은 웹페이지 즐겨찾기