nums
는 숫자로 이루어진 배열입니다.
가장 자주 등장한 숫자를 k
개수만큼 return해주세요.
nums = [1,1,1,2,2,3],
k = 2
return [1,2]
nums = [1]
k = 1
return [1]
function topK(nums, k) {
let arr = [];
nums.forEach((el) => {
arr[el] = arr[el] ? arr[el] + 1 : 0 + 1;
});
const sortedAndSliced = [...arr].sort((a, b) => b - a).slice(0, k);
let resultArr = [];
for (i = 0; i < k; i++) {
resultArr.push(arr.indexOf(sortedAndSliced[i]));
}
return resultArr;
}
발상 : 지난번에 비슷한 문제가 있었을 때는 nums에서 숫자-등장한 갯수를 Object의 key-value로 접근해 풀었다. 이번에는 array에 index라는 숫자가 이미 존재한다는 점에 착안해 nums에서 숫자-갯수를 array의 index-요소의 값 으로 저장하는 방법을 썼다.
nums.forEach()로 nums의 각 요소(el)에 접근해, arr[el] 이 존재하지 않으면 0으로 초기화한 후 1을 더하고, 이미 존재하는 경우 바로 1을 더하는 방식으로 갯수를 센다.
예로 nums = [1,1,1,2,2,3]일 때 arr = [<1 empty item>, 3, 2, 1] 이 된다.
[...arr] 로 arr를 복사한 새 배열을 만들고, sort((a, b) => b - a)로 내림차순으로 정렬한 후, slice(0,k)로 가장 큰 숫자를 k개만큼 뽑은 배열을 sortedAndSliced 에 저장한다.
k = 2 일 때 sortedAndSliced = [3, 2] 가 된다.
그 뒤 sortedAndSliced의 각 요소를 arr.indexOf()를 이용해 arr에서 어느 숫자인지 찾은 뒤 resultArr에 순서대로 push 하고, resultArr를 return 한다. resultArr = [1, 2] 가 된다.
이 때 arr를 활용해야 하므로 아까 sortedAndSliced를 선언할 때 arr에 바로 .sort() 를 사용하지 않고(.sort() 배열 메서드는 원 배열의 순서를 변경한다) 펼침 연산자를 이용해 [...arr].sort() 로 arr를 복사한 새 배열을 정렬하였다.