알고리즘을 풀다보니 Map 객체라는 것을 새로 알게 되었다.
그래서 정리해보며 다른 사람들과 내가 쉽게 이해한대로 공유하면 좋겠다 생각이 들었다.
먼저 풀었던 문제는 다음과 같다
사실 이 문제는 처음에 30분동안 풀지 못해 풀이를 이해하고, 다시 풀게 되었다.
근데 다시 풀면서도 Map을 까먹어 버린 것이다. 그래서 다음과 같이 풀이를 했다.
function solution(id_list, report, k) {
var answer = [];
report=[...new Set(report)];
let reporterObj=new Object();
id_list.map((v)=>{ // id별로 신고 성공횟수 0으로 초기화
reporterObj[v]?1:reporterObj[v]=0;
})
let reportedObj=new Object();
report.map((v)=>{ // 신고 받은 id 횟수
let [reporter,reportee]=v.split(" ");
reportedObj[reportee]?reportedObj[reportee]++:reportedObj[reportee]=1;
})
Object.keys(reportedObj).map((v)=>{
if(reportedObj[v]>=k){
report.forEach((element)=>{
let [reporter,reportee]=element.split(" ");
if(reportee===v){
reporterObj[reporter]?reporterObj[reporter]++:reporterObj[reporter]=1;
}
})
}
}) // 만약 특정 id가 두번 이상 신고 당했다면, 그 신고당한 id를 신고한 신고자 +1
id_list.map((v)=>{
if(reporterObj[v]===null){
answer.push(0);
}else{
answer.push(reporterObj[v]);
}
})
return answer;
}
이런 엉터리 알고리즘을 먼저 보여주게되어 죄송하단 말씀을 먼저 하겠습니다.
프로그래머스에 돌리면 map을 4번이나 돌리니 당연히 시간 초과가 난다.
풀면서도 아 이게 맞는 방법이긴한데... 효율성이 엉망이네 하면서 풀었다.
그래서 배열 중복 제거 방법과 Map 객체에 대해 정리해보고자 한다.
정말정말 쉽다. Set 객체를 이용하는 방식이다.
Set은 중복된 값은 가질 수 없다는 게 특징이다.
그렇기에 배열을 Set으로 변환한 뒤 다시 배열로 바꿔주는 방법이다.
위의 풀이에서 보면
report=[...new Set(report)];
이 부분이 배열 중복제거에 해당한다.
report를 Set으로 바꿔준 뒤, 다시 []로 감싸주어 배열로 바꿔주는 것이다.
실제 결과를 보면 차이를 느낄 수 있다.
배열 바꿔주기 전
["ryan con", "ryan con", "ryan con", "ryan con"]
바꿔준 후
["ryan con"]
map()함수는 많이 사용하지만 Map 객체에 대해서는 잘 모르고 있었다.
let max = new Map();
// set으로 맵 객체에 삽입
max.set('id', 0);
max.set('이름', '마이클');
max.set('전공', '영문학');
max.set('나이', 25);
// 이차원 배열로 넘겨주는 것도 가능합니다
let michael = new Map([
['id', 0],
['이름', '마이클'],
['전공', '영문학'],
['나이', 29],
]);
// get으로 맵 객체 조회
max.get('이름'); // "마이클"
// delete로 삭제
max.delete('나이'); // 삭제가 성공하면 true를 반환
// clear로 맵 안의 프로퍼티 전부삭제
max.clear();
다음과 같이 key: value 형태로 이루어져있다. key로 조회, 삭제가 가능하고 문자열 아닌 값도 key로 사용할 수 있다는 장점이 있다. Map 객체는 중복을 허용하지 않는다.
위의 문제를 Map 객체를 이용해서 다시 풀어봤다.
function solution(id_list, report, k) {
var answer = [];
let reports=[...new Set(report)].map((v)=>{return v.split(" ")});
let count=new Map();
reports.map((v)=>{ // v[1]은 신고받은 사람
count.set(v[1],count.get(v[1])+1||1);
});
let good=new Map();
reports.map((v)=>{ // id별 신고 성공 횟수
if(count.get(v[1])>=k){
good.set(v[0],good.get(v[0])+1||1);
}
})
answer=id_list.map((v)=>good.get(v)||0);
return answer;
}
이렇게 하니 시간 초과도 발생하지 않고 풀렸다.
결론
Map 객체를 활용하면 Object를 여러개 생성하는 것보다 편리하다!