D.evelop [CS]/Algorithm
[Algorithm 010] JS - moreThanHalf
Danne
2021. 10. 2. 22:47
Q. 숫자로 이루어진 배열인 nums를 인자로 전달합니다. 숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.
예를 들어,
nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2
- 조건 : nums 배열의 길이는 무조건 2개 이상
A. 처음 답
function mortThanHalf (nums) {
let obj = {};
nums.forEach((x)=>{
obj[x] = (obj[x] || 0)+1;
})
const value = Object.values(obj).sort((a,b) => {return b - a})[0];
const max = Object.keys(obj).filter((a)=>obj[a]===value?true:false)[0]
return Number(max)
}
mortThanHalf([2,2,1,1,1,2,2])
✔️해석
function mortThanHalf (nums) {
let obj = {};
// nums으로 받아오는 배열의 각 요소을 돌며 함수를 실행하겠다.
// 각 요소를 x라 칭하겠다.
nums.forEach((x)=>{
obj[x] = (obj[x] || 0) + 1;
// obj객체의 key로 각 요소 값(x)를 사용하겠다.
// [2,2,1,1,1,2,2]의 경우?
// 함수 첫 실행 시, obj[2]가 됨
// 원래 2라는 key값이 없으니까 새로 추가해 줌 (
// let obj = { '2' : ?? }가 됨
// 즉, '2'라는 key값을 세팅하는 용도
// !! 이때 key값으로 들어가면서 number는 string타입이 됨
// 그리고 +1 을 함 ('이제 1개가 있다!')
// let obj = { '2' : 1 }
// 두번 째 실행시,
// 되고 obj[2]되고, 이번엔 { '2' : 1 } 가 있으므로
// obj[2] = (obj[2]의 값) + 1
// let obj = { '2' : 2 }
// 이렇게 쭉 돌아감
}) // { '1': 3, '2': 4 }
const value = Object.values(obj).sort((a,b) => {return b - a})[0];
// Object.values()로 obj객체의 value만으로 이루어진 배열을 구함
// [ 3, 4 ]
// 이 배열의 값들(values)을 sort()메서드를 사용해 내림 차순으로 정렬함
// [ 4, 3 ]
// 그 중 1번 째 값을 value라는 변수에 담음
// [ 4 ]
const max = Object.keys(obj).filter((a)=>obj[a]==value?true:false)[0]
// Object.keys()로 obj객체의 key만으로 이루어진 배열을 구함(key값이라 string으로 담김)
// [ '1', '2' ]
// 이 배열의 값(keys)을 이용해 배열을 순회하면서 filter()메서드를 사용해 value값인 4와 같은 같을 가진 요소(key)를 찾아 배열로 만듦
// [ '2' ]
// 그 중 1번 째 값을 max에 담음
return Number(max)
//string인 max 값을 number형으로 변환해서 반환
}
mortThanHalf([2,2,1,1,1,2,2])
// 오름차순 정렬
arr.sort((a,b) => {return a - b});
// 내림차순 정렬
arr.sort((a,b) => {return b - a});
하지만 const max값을 선언하는 부분에서
- const value의 값은 1개의 number형 값
- key에는 중복된 값이 없음
- 동등연산자의 기본값은 boolean형이므로 true:false 를 따로 설정할 필요 없음
- Number()메서드는 배열값도 숫자로 바꿔 줌
위와 같은 이유로 이렇게 줄일 수 있다.
function moreThanHalf(nums) {
let obj = {};
nums.forEach((x) => {
obj[x] = (obj[x] || 0) + 1;
})
const value = Object.values(obj).sort((a,b) => {return b - a})[0])
const max = Object.keys(obj).filter((e)=>obj[e]==value)
return Number(max)
}
포스팅 중에 인지한 문제!
위 로직에서는 다음과 같이 3이 과반수를 넘지 않은 경우에도 3을 출력해주고 있었다.
문제를 다시 보면
숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환
이라고 되어있고, 내가 처음으로 구한 로직은 가장 많이 있는 숫자를 반환한 것
// 위 로직의 결과 : 3이 과반수를 넘지 않는데 3을 반환하고 있다.
nums = [2,2,1,1,1,3,3,3,3]
return 3
// nums.length를 2로 나눠 전제 배열의 과반수를 초과하는 수를 구한다.
// 배열의 길이가 홀수일 경우도 있으므로, Math.floor()를 사용해 내림을 한다.
// 배열의 길이가 7일 경우 7 / 3 = 3.5. 이 값을 내림하면 3
// 즉, 배열에서 제일 많은 숫자가 4개 보다 많아야 과반수가 되는 것
if(Math.floor(nums.length / 2) < value){
return Number(max)
}else{
return '가장 많은 수 :'+ max
}
B. 최종 답
function moreThanHalf(nums) {
let obj = {};
nums.forEach((x) => {
obj[x] = (obj[x] || 0) + 1;
})
const value = Object.values(obj).sort((a,b) => {return b - a})[0];
const max = Object.keys(obj).filter((e)=>obj[e]==value)
if(Math.floor(nums.length / 2) < value){
return Number(max)
}else{
return '가장 많은 수 :'+ max
}
}
moreThanHalf([2,2,1,1,1,3,3,3,3,3,3]) // 3
moreThanHalf([2,2,1,1,1,3,3,3,3,3]) // '가장 많은 수 :3'
반응형