레벨 0 문제였다.
그렇지만 오늘의 나는 혼자서 풀지 못했다..😂
이 문제를 씹어먹겠다는 ㅋㅋㅋㅋ 강한 의지로 답안을 하나하나 뜯어보았다😼
간단히 말하면 문제는 배열에 들어있는 값들 중 가장 많이 나온 값을 리턴하면 되고,
가장 많이 나온 값이 한개가 아닐 경우 -1을 리턴하면 되었다.
이 문제를 뜯어보려고 다른 사람들의 풀이를 살펴보다 보니 정말 풀이 방법이 다 달랐다. .
이제까지 내가 풀었던 문제 대부분은 풀이 유형이 3가지 정도로 정리되었다.
그만큼 배울게 많은 문제였다 😃😆
처음에 나는 빈 obj 설정후, 반복문으로 풀려고 했다. ㅋㅋㅋㅋ
그런데 4시간을 붇잡아도 계속 정답률이 100%가 나오지 않았다...
일단 정답을 살펴보자.
1.
function solution(array) {
let arr = new Map();
for(let i=0; i<array.length; i++){
arr.set(array[i], (arr.get(array[i]) || 0)+1);
}
let max = Math.max(...[...arr].map((a)=>{return a[1]}))
let count = [...arr].filter((a)=>{return a[1] ===max}).length
if(count >1){
return -1
}else{
return [...arr].find((v) => {return v[1] === max})[0];
};
}
solution([1,2,3,3,3,4])
좀더 하나하나 뜯어보자.
function solution(array) {
//생성자 함수를 이용해서 Map 자료를 arr라는 변수에 담아두었다.
let arr = new Map();
//반복문을 이용해서 arr라는 Map 자료형에 요소들을 집어넣었다.
for(let i=0; i<array.length; i++){
//arr.set(키 , 값) 이렇게 하면 키와 값이 들어간다. (Map 자료형은 obj와 다름)
arr.set(array[i], (arr.get(array[i]) || 0)+1);
//그런데 값을 넣는 공간에 or연산자가 들어가 있다.
//array[i]를 키로 가지고 있는 값을 불러오는데, 만약 그것이 없다면 undefined 일 것이다.
//undefined인 경우 false에 해당하고, or 연산자는 모두가 false 이면 마지막 값을 반환한다.
//그럼 아직 값이 할당되지 않은 경우, (arr.get(array[i]) || 0)는 0이고,
//+1을 하기때문에 1이 할당된다.
}
//arr에는 이렇게 담겨있다.
//Map(4) {1 => 1, 2 => 1, 3 => 3, 5 => 1}
let max = Math.max(...[...arr].map((a)=>{return a[1]}))
//[...arr] 이 말은 Map 자료가 담겨있는 arr를 spread operator를 이용해서 풀어서 배열로 담아준다.
//[[1, 1],[2, 1],[3, 3],[4, 1]]]
//그리고 이 자료를 반복하면서 작은 배열 하나하나의 [1]번째 값을 return 한다.
//[...arr].map((a)=>{return a[1]} 의 값은 [1,1,3,1] 이 나온다.
//Math.max()함수는 괄호 안에 있는 값들 중에서 최댓값을 반환하는데, 배열의 상태로는 넣을 수 없다.
//그래서 또 한번 spread operator를 사용해서 Math.max함수에 넣어준다.
//이렇게 max에는 arr 값의 최대값이 담겼다.
let count = [...arr].filter((a)=>{return a[1] ===max}).length
//[[1, 1],[2, 1],[3, 3],[4, 1]]]이걸 filter 해서 새로운 배열을 내주겠다는 말이다.
//조건으로 배열의 요소인 작은배열에 1번째 요소가 max와 같은 경우만 리턴하고,
//그것의 길이를 count에 넣어준다.
// 즉 가장 큰값이 1개라면 1을 넣어주고, 2개라면 2를 넣어준다.
if(count >1){ //만약 count가 여러개라면,
return -1
}else{ //count가 1개라면,
return [...arr].find((v) => {return v[1] === max})[0];
//[[1, 1],[2, 1],[3, 3],[4, 1]]]여기서 조건에 해당하는걸 찾는다.
// 작은배열의 1번째 요소가 max와 같은 작은 배열만 찾아서,
// 그것의 0번쨰 요소를 리턴한다.
};
}
solution([1,2,3,3,3,4])
정답2.
function solution(array) {
const obj = {};
let val = 0;
let key = 0;
for(let e of array){
obj[e]===undefined? obj[e] = 1 : obj[e]++
if(obj[e]>val){
val = obj[e];
key = e;
}else if(obj[e] === val && e!==key ){
key = -1;
}
}
return key;
}
solution([1,2,3,3,3,4])
뜯어보기
function solution(array) {
const obj = {};
let val = 0;
let key = 0;
//이터러블 객체인 array는 for of 반복문이 가능하다.
for(let e of array){
//obj에 num키에 값이 아직 할당되지 않았을 경우. obj에 num이라는 키를 주고, 그 값을 1로 할당.
//그게 아니라면, 즉 이미 num키에 값이 할당되어 있다면 값을 1씩 증가시킬것.
obj[e]===undefined? obj[e] = 1 : obj[e]++
// 만약 obj[num]의 값이 maxCount 보다 클 경우 maxCount에 obj[num]을 재할당. 즉 몇개 있는지.
// 그리고 mostFrequent 에는 키를 넣어준다. 즉 어떤 숫자인지 넣어줌.
if(obj[e]>val){
val = obj[e]; //1 1 3
key = e; //1 2 3
}else if(obj[e] === val && e!==key ){
//만약 obj[num]의 값이 이미 있는 최댓값과 같고, 해당 키가 이미 샌 키가 아니라면, -1을 할당함.
key = -1;
}
}
return key;
}
solution([1,2,3,3,3,4])
정답3.
function solution(array) {
let m = new Map();
for (let n of array) m.set(n, (m.get(n) || 0)+1);
//m을 출력하면, {1 => 1},{2 => 1},{3 => 3},{4 => 1}
//1번 과정과 여기가 다른데, sort는 오름차순 혹은 내림차순 정렬을 해주는 함수이고,
//spread operator를 이용해 배열로 만든 m을 하나하나 꺼낸것.
//즉 작은배열a[1,1] 과 또다른 작은배열b[2,1] 을 가지고,
//각각의 작은배열의 1번째 요소의 값을 비교해서 내림차순으로 정렬.
m = [...m].sort((a,b)=>b[1]-a[1]);
//m을 출력하면 [3, 3], [1, 1], [2, 1], [4, 1]
//or연산자와(둘중 하나라도 true 라면 true 반환.), 3항연산자를 이용했다.
//m의 길이가 1과 같거나, "m의 0번째 요소의 1번째 요소"가 "1번째 요소의 1번째 요소"보다 크다면
//즉 m이 한개 있거나, 최빈값이 1개라면 내림차순 정렬한 m의 0번째 요소의 0번째 요소를 가져와줘. 즉 키를 가져와줘.
//그게 아니라 m의 길이가 1보다 큰데, 최빈값이 여러개라면 -1 리턴
return m.length === 1 || m[0][1] > m[1][1] ? m[0][0] : -1;
}
solution([1,2,3,3,3,4])
정답4.
const solution = (array) => {
const counter = array.reduce((acc, cur) => ({
...acc,
[cur]: (acc[cur] || 0) + 1
}), {})
const items = Object.keys(counter).map((key) => [
Number(key), counter[key]
]).sort((a, b) => b[1] - a[1])
if (items[0][1] === items?.[1]?.[1]) {
return -1
}
return items[0][0];
}
solution([1,2,3,3,3,4])
뜯어보기
const solution = (array) => {
const counter = array.reduce((acc, cur) => ({
...acc,
[cur]: (acc[cur] || 0) + 1
}), {})
const items = Object.keys(counter).map((key) => [
Number(key), counter[key]
]).sort((a, b) => b[1] - a[1])
if (items[0][1] === items?.[1]?.[1]) {
return -1
}
return items[0][0];
}
solution([1,2,3,3,3,4])
정답 5.
function solution(array) {
let setArr = [...new Set(array)];
let calArr = setArr.map((v,i) => array.filter(dv => dv == v).length);
let rsltArr = calArr.map((mv,mi) => { if(mv == Math.max(...calArr)) return mi; return -1}).filter(v => v != -1)
return rsltArr.length > 1 ? -1 : setArr[rsltArr[0]];
}
solution([1,2,3,3,3,4])
정답 6.
function solution(array) {
const counts = array.reduce((a, c) => (a[c] ? { ...a, [c]: a[c] + 1 } : { ...a, [c]: 1 }), {});
const max = Math.max(...Object.values(counts));
const modes = Object.keys(counts).filter(key => counts[key] === max);
return modes.length === 1 ? +modes[0] : -1;
}
solution([1,2,3,3,3,4])
- Map 자료형을 활용하는 방법도 있다.
- 콜백 함수에서 화살표 함수로 표현할 때에, 파라미터가 1개이고, return 문이 한줄일 때에, 콜백함수 내부의 괄호와, 중괄호, return 을 생략할 수 있다. (예) .find(v => v[1] ===max) 이런식으로.)
'코딩테스트' 카테고리의 다른 글
; 을 안쓰면 일어나는 일...(split과 구조분해할당 에서 벌어진 일) (0) | 2023.09.26 |
---|---|
가위바위보 프로그래머스 코딩테스트 문제 (1) | 2023.09.21 |
문자열의 끝에 이 문자가 있니? endWith() / substr() (0) | 2023.09.13 |
"2개 숫자 모두 배수라면 1을 리턴해주세요" 공배수 문제 or연산자 이용한다구??? (0) | 2023.09.13 |
비트 연산자 _ shift operator (<<) (0) | 2023.09.08 |