JavaScript 정리-5 프그 풀이(신고 결과)

Kyoungchan Cho·2022년 12월 27일
0

JS

목록 보기
5/8
post-thumbnail

프로그래머스 풀며 정리(5)

문제 : 2022 KAKAO BLIND RECRUITMENT > 신고 결과 받기
https://school.programmers.co.kr/learn/courses/30/lessons/92334

본인 풀이(오답)

  1. 중복 신고를 제거한 이차원 배열 reportArray을 만든다.
  2. 신고 당한 유저를 배열 원소로 받으면서 전체 유저의 인덱스와 같은 이차원 배열reportedUsers을 만든다.
  3. 전체 유저 id_list를 key값, 그리고 2번에서 뽑은 배열 reportedUsers를 value값으로 받는 객체ObjectId를 만든다.
  4. 신고당한 유저 중 정지당한 유저를 담은 배열 susUser를 구한다.
  5. 3번에서 뽑은 객체objectId와 4번에서 뽑은 정지당한 유저 리스트susUser 배열을 이중반복문을 돌려서 objectId의 value값이 정지당한 유저 배열의 포함(includes)됐을 때 카운팅을 올리고 그 카운트를 정답 배열에 푸쉬하고 리턴한다.

결국 통과하지 못하고 80~90점 초반까지 점수를 받은 풀이이다. 인자로 받는 배열 report의 경우 범위가 1 ≤ report의 길이 ≤ 200,000 이고, report를 활용한 신고당한 유저 reportedUsers를 이차원 배열로 사용하여 반복문, 이중 반복문을 자주 사용하게 된다. 마지막 정답을 리턴 할때는 .includes()를 쓰기 때문에 또 루프가 더 돌게 되고.. 그래서 3,10,11 테스트의 경우 시간초과로 통과하지 못한다.


function solution(id_list, report, k) {

    //1. 중복 신고 제거한 이차원 배열 만들기
    const reportArray = [...new Set(report)].map(x => x.split(" "))
    
    //2. 신고 당한 유저를 배열 원소로 받으면서 전체 유저의 인덱스와 같은 이차원 배열을 만듬
    let reportedUsers = [];
        
        for(i in id_list) {
            let indivisualReportArray = [];
            for(j in reportArray) {
                if(reportArray[j][0] === id_list[i]){
                    indivisualReportArray.push(reportArray[j][1])
                }
            }
            reportedUsers.push(indivisualReportArray)
       }
  
	//3. 전체 유저 `id_list`를 key값, 그리고 2번에서 뽑은 배열 `reportedUsers`의 원소들을 value값으로 받는 객체`ObjectId`를 만든다.
    const objectId = {}
    id_list.forEach((key, i) => objectId[key] = reportedUsers[i])

  
    //4. 신고당한 유저 중 정지당한 유저를 구한다.       
    const getSusUser = (reportedUsers, k) => {
        
        //신고당한 유저 이차원배열 => 1차원배열
        let newReportedUsers = reportedUsers.flat()
                                                     
        // 신고당한 유저(key)와 신고당한 횟수(value)로 이루어진 객체를 만든다. (중복횟수 체크)
        const reportedUserCount = {};
        newReportedUsers.forEach(x => {
            reportedUserCount[x] = (reportedUserCount[x] || 0) +1
        })
        
        //위 객체에서 신고당한 횟수(value)가 k이상인 key를 뽑아 배열로 리턴한다.
        let susUser = [];
        for(const key in reportedUserCount) {
            if(reportedUserCount[key] >= k)
                susUser.push(key)
        }
        
        return susUser
    }
    
    //정지당한 유저 리스트 배열
    const susUser = getSusUser(reportedUsers, k)
      
    
    //5. 메일받은 횟수(정답) 뽑기
    //3번에서 뽑은 객체`objectId`와 4번에서 뽑은 정지당한 유저 리스트`susUser` 배열을 이중반복문을 돌려서 `objectId`의 value값이 정지당한 유저 배열의 포함(includes)됐을 때 카운팅을 올리고 그 카운트를 정답 배열에 푸쉬하고 리턴한다.  
    let answerArray = []
    
    for(const key in objectId) {
        let count = 0;
        for(i in susUser) {
            if(objectId[key].includes(susUser[i])) {
                count++
            }
        }
        answerArray.push(count)
    }
    return answerArray
}

지인 풀이를 참고한 통과한 정답 풀이

  1. 중복 신고를 제거한 배열 newReport을 만든다.
  2. 신고당한 유저의 목록을 일차원 배열 reportedUsers로 받는다.
  3. 신고 당한 유저를 카운팅하고 정지당한 유저의 목록을 key값, 그리고 그 유저가 신고당한 횟수를 value값으로 받은 객체 suspenededUserObject를 만든다.
  4. 정지당한 유저를 신고한 유저의 목록을 나열한 배열로 만든다.
    이 부분이 이해하는데 오래걸렸다. if문에 있는 객체의 key값으로 다른 배열의 원소를 넣는 방법을 이번에 배우게 됐다. 그리고 1번에서 뽑은 newReport와 2번에서 뽑은 reportedUsers의 길이가 같기 때문에 같은 반복문안에서 처리하며 정지당한 유저를 신고한 유저를 나열한 배열을 구할수 있게 된다.
  5. 4번을 활용하여 정지 메일을 받은 유저를 key, 그 메일 수신 횟수를 value로 한 객체mailCountObject를 만든다.
  6. 전체 유저 목록인 배열 id_list의 원소가 5번에서 뽑은 객체 mailCountObject의 key일 경우 mailCountObject의 value를 정답 배열에 넣는다. 존재하지 않을 경우(else) 0을 푸시한다.

본인 풀이와 차이점은 reportedUsers를 일차원 배열로 만들기 때문에 이중반복문을 한번 줄일 수 있는 것과 배열의 반복문 중 배열의 원소를 비교하는 객체의 key값으로 활용하여 .includes()나 이중반복문을 줄인다는 점이다.

function solution(id_list, report, k) {

    //1. 중복 신고를 제거한 이차원 배열 만들기
    const newReport = [...new Set(report)].map(x => x.split(" "))
    
    //2. 신고당한 유저의 목록을 일차원 배열 `reportedUsers`로 받는다.
    let reportedUsers = [];
    for(i in newReport) {
        reportedUsers.push(newReport[i][1])
    }

    //3. 신고 당한 유저를 카운팅하고 정지당한 유저의 목록을 key값, 그리고 그 유저가 신고당한 횟수를 value값으로 받은 객체 `suspenededUserObject`를 만든다.      
    const getSusUser = (reportedUsers, k) => {
                                             
        // 신고당한 유저와 그 카운트를 객체로 만든다.
        const reportedUserCount = {};
        reportedUsers.forEach(x => {
            reportedUserCount[x] = (reportedUserCount[x] || 0) +1
        })
        
        //바로 위에서 만든 객체 중 value가 k보다 작을 경우 삭제한다 => 정지당한 유저만 남는다.
        for(const key in reportedUserCount) {
            if(reportedUserCount[key] < k)
                delete reportedUserCount[key]
        }
        
        return reportedUserCount
    }
    
    //정지당한 유저의 목록을 key값, 그 유저가 신고당한 횟수를 value값으로 받는 객체
    const suspendedUserObject = getSusUser(reportedUsers, k)
    
    //4. 정지당한 유저를 신고한 유저의 목록을 나열한 배열로 만든다.
    // (신고당한 유저 목록 배열`reportedUsers`의 원소)가 (정지당한 유저 목록 객체 `suspendedUserObject`의 key와 동일할 경우) (1번에서 뽑은 이차원 배열 `newReport` 중 신고자를 뜻하는 원소 newReport[i][0]을) (빈 배열에 push하여 정지당한 유저를 신고한 유저의 목록을 나열한 배열`reporterArray`를 만든다).
    // 문장 호흡이 길어져서 헷갈리지 않게 괄호로 감싸겠다.
    let reporterArray = [];
    for (i in reportedUsers) {
        if(reportedUsers[i] in suspendedUserObject) {
            reporterArray.push(newReport[i][0])
        }
    }

    //5. 정지 메일을 받은 유저를 key, 그 메일 수신 횟수를 value로 한 객체를 만든다.
  	//위 4번에서 뽑을 배열 `reporterArray`은 정지당한 유저를 신고한 유저의 나열이기 때문에 중복 개수를 체크하여 메일 받은 유저와 메일 수신 횟수를 구한다.
    const mailCountObject = {}
    reporterArray.forEach(x => {
        mailCountObject[x] = (mailCountObject[x] || 0) +1
    })
    
    
    //6. 전체 유저 목록인 배열 `id_list`의 원소가 5번에서 뽑은 객체 `mailCountObject`의 key일 경우 `mailCountObject`의 value를 정답 배열에 넣는다. 존재하지 않을 경우(else) 0을 푸시한다.
    let answerArray = []
    
    for(i in id_list) {
        if(id_list[i] in mailCountObject) {
            answerArray.push(mailCountObject[id_list[i]])
        }
        else(answerArray.push(0))
    }
    return answerArray
}
profile
https://lying-lettuce-69f.notion.site/KyoungchanCho-Blog-f9f150b9e3be4467a67cf2a21932650d (게시글 자동 비공개 현상으로 일단 노션으로 이동합니다. 소개에서 URL 링크 클릭으로 연결됩니다.)

0개의 댓글