https://www.acmicpc.net/problem/2108
const input = ["5", "1", "3", "8", "-2", "2"];
let answer = "";
const N = Number(input.shift());
const numbers = input.map(Number).sort((a, b) => a - b);
// 산술평균
answer += `${Math.round(numbers.reduce((a, b) => a + b, 0) / N)}\n`;
// 중앙값
answer += `${numbers[Math.floor(N / 2)]}\n`;
// 최빈값
const map = new Map();
let max = 1;
for (let number of numbers) {
if (map.has(number)) {
max = Math.max(max, map.get(number) + 1);
map.set(number, map.get(number) + 1);
} else map.set(number, 1);
}
const maxArr = [];
for (let [key, val] of map) {
if (val === max) maxArr.push(key);
}
answer += maxArr.length === 1 ? `${maxArr[0]}\n` : `${maxArr[1]}\n`;
// 범위
answer += `${numbers[N - 1] - numbers[0]}\n`;
console.log(answer);
주어진 N개의 수의 산술평균, 중앙값, 최빈값, 범위를 구하는 문제
solved.ac 기준 실버3의 난이도에 비해 문제가 많이 쉽다고 느꼈는데.. 함정은 최빈값에 있었다.
나머지 3개에 비해 많은 고민을 하게 만든 최빈값 처음에는 Set 자료구조를 통해 개수를 샌 후
인덱스 위치로 해당 숫자의 개수를 파악하는 식의 주먹구구식으로 진행했다가 엄청난 실패를 경험하고 map을 사용하는 법을 공부한 후 적용하였더니 코드가 매우 간결해졌다.
가장어려웠던 최빈값
반복문을 통해 주어진 숫자들을 순회하고, map 자료구조에 없는 숫자이면 해당 숫자를 key 값으로 value 값은 초기값을 1로 설정해준다.
있는 숫자이면, 현재의 max값과 해당 number의 value 값에 1을 더한 값중 더 큰값을 현재 max 값으로 설정하고, 현재 number 값의 value 를 1증가 시켜주는 코드를 작성하였다.
그러면 map 자료구조 안은 (number, number의 개수) 이런 모습일 것이다.
가장 많이 출현한 숫자를 기록해주기위해 maxArr 이라는 배열을 선언하여 map 을 반복문으로 순회한다.
만약 map의 value 값이 max 값과 동일하다면 그 수는 가장 많이 출현한 수이기 때문에 key값을 maxArr 배열에 넣어준다.
마지막으로 maxArr 의 길이가 1이상이면 두번째로 작은 수, 아니라면 그 값이 최빈값이다.
map 자료구조에 대해 배울수 있었던 좋은 문제였던것 같다.