문제링크
https://school.programmers.co.kr/learn/courses/30/lessons/120812
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명
최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.
제한 사항
0 < array의 길이 < 100
0 ≤ array의 원소 < 1000
입출력 예
array | result |
[1, 2, 3, 3, 3, 4] | 3 |
[1, 1, 2, 2] | -1 |
[1] | 1 |
입출력 예 설명
입출력 예 #1
[1, 2, 3, 3, 3, 4]에서 1은 1개 2는 1개 3은 3개 4는 1개로 최빈값은 3입니다.
입출력 예 #2
[1, 1, 2, 2]에서 1은 2개 2는 2개로 최빈값이 1, 2입니다. 최빈값이 여러 개이므로 -1을 return 합니다.
입출력 예 #3
[1]에는 1만 있으므로 최빈값은 1입니다.
나의 풀이
function solution(array) {
const num= new Map();
for(let n of array){
if(!num.has(n)) num.set(n,1); //처음만난 수, Map에 추가
if(num.has(n)) num.set(n,num.get(n)+1);//Map에 있을 경우 카운트+1
}
let sorted= [...num].sort((a,b)=> b[1]-a[1])//value를 기준으로 내림차순정렬
if(sorted.length>1 && sorted[0][1]===sorted[1][1]) return -1 //최빈값이 여러개인 경우
else return sorted[0][0]; //내림차순 중 가장 큰 값인 첫 번째 원소.
}
- Map 객체 생성 (key-value값을 담는 객체 데이터타입) => {array의 원소: 나온 개수} 식으로 담음
- array의 원소 하나하나를 돌면서 처음 나온 경우 set을 통해 Map 객체에 추가 해줌. 이때 한 번 나왔으므로 1로 value설정
- num Map객체에 이미 존재할 경우, set함수를 사용해 key가 n인 값의 value를 1 올려줌. get(n)은 key가 n인 값의 value를 반환함.
- Map을 [...num]으로 배열타입으로 바꾼 후 ([[원소1, 나온 개수], [원소2, 나온개수]] 이런식으로 2차원 배열이 됨 ), value를 기준으로 내림차순 정렬. b[1]-a[1]을 통해 두 번째 원소를 기준으로 정렬함.
- 최빈값이 여러 개인 경우는 내림차순 정렬된 배열에서 첫 번째 값과 두 번째 값이 같은 경우임. 이때 원소가 하나인 경우는 배제해야 함으로 sorted.length>1을 조건으로 넣음
- if 조건에 해당하지 않는다면 가장 큰 값은 첫 번째 원소의 키값 즉 sorted[0][0]
다른 사람 풀이
function solution(array) {
let m = new Map(); //Map생성
for (let n of array) m.set(n, (m.get(n) || 0)+1); //array를 돌면서 key값에 대해 m.get(n)이 없다면 1로 해서 set
m = [...m].sort((a,b)=>b[1]-a[1]); //위와 동일
return m.length === 1 || m[0][1] > m[1][1] ? m[0][0] : -1;
// m의 길이가 1이면 m[0][0]반환
//m의 길이가 1이 아니면 m[0][1]>m[1][1] 검사
//이때 최빈값이 중복이라면-1을 반환, 중복이 아니라면 m[0][0]반환
}
- 내 코드와 전체적으로 비슷하지만 짧게 잘 썼다.
- 마지막 return에서 좀 복잡해보였는데 or (||) 연산자는 short-circuiting으로 앞의 연산이 true라면 뒤를 검사하지 않는다. m.length가 1인 경우는 m[1][1]이 존재하지 않기 때문에 그 때 오류를 피하기 위해 or 연산자를 사용한 것 같다.
배운 점
- or 연산자의 short-circuiting 활용. 입력된 배열의 길이가 어떻게 될지 모르니 m[1][1]과 같이 배열의 길이에 따라 오류가 날 수 있는 것을 예방하자.
- Map.set에서 (n, (m.get(n) || 0) +1) : m.get(n)은 해당 key값이 없을 경우 undefined를 반환하는데 이는 false이다. 즉 ||연산자를 활용해 해당 key값일 경우 m.get(n)을 사용하고 없을 경우 0을 선택적으로 쓸 수 있다.
- Map 객체: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 Lv.0] 다음에 올 숫- 자바스크립트 풀이, javaScript (0) | 2023.07.21 |
---|---|
[프로그래머스 Lv.0] 분수의 덧셈- 자바스크립트 풀이, javaScript (0) | 2023.07.21 |
[프로그래머스 Lv.0] OX퀴즈 - 자바스크립트 풀이, javaScript (0) | 2023.07.21 |
[프로그래머스 Lv.0] 문자열 밀기 - 자바스크립트 풀이, javaScript (0) | 2023.07.20 |