배꼽파지 않도록 잘 개발해요

99클럽 코테 스터디 5일차 TIL - 완주하지 못한 선수 본문

코딩테스트/99클럽

99클럽 코테 스터디 5일차 TIL - 완주하지 못한 선수

꼽파 2024. 7. 26. 16:16


완주하지 못한 선수

출처 : 프로그래머스 Lv.1

문제 설명

  • 수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
  • 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

풀이 1 : Object

function solution(participant, completion) {
	// 빈 객체의 key: 참가자 이름, value: 등장 횟수
    const obj = {};
    
    // 객체에 선수의 이름 파악
    // 이름 이미 존재한다면, value값만 증가
    // 이름이 없다면, 1로 초기화해줌.
    for (let i = 0; i < participant.length; i++) {
        if (obj[participant[i]]) obj[participant[i]]++;
        else obj[participant[i]] = (undefined || 1);
    }
    
    // 배열을 순회하면서 객체에 선수 이름의 횟수를 감소시킴.
    // 이렇게 되면 완주한 선수들은 1 -1이 되어서 총 0이 됨.
    for (let i = 0; i < completion.length; i++) {
        obj[completion[i]]--;
    }
    // console.log(obj) // { leo: 1, kiki: 2, eden: 2 }
    // console.log(Object.keys(obj))
    
    // 객체에서 값이 0이 아닌 키(선수명단)을 출력함.
    return Object.keys(obj).filter(el => obj[el] !== 0).join("");
}
  • || 연산자는 왼쪽 항의 값이 거짓이면 오른쪽 항의 값을 반환함. 기본값을 1로 설정해주기 위해 사용함.
  • 기본 아이디어는 객체를 만들어서 각 배열 속 선수의 명단을 키로 넣고, 값은 시작(+1), 완주(-1)을 적용하여 완주한 선수는 0이 되도록 함.
  • 완주하지 못한 선수들의 명단은 해당 객체에서 0이 아닌 값을 출력하면 됨. 

풀이2 : map

function findNonFinisher(participant, completion) {
    // 각 참가자 이름과 그 출현 횟수를 기록할 해시 맵 생성
    const participantMap = new Map();

    // 참가자 목록을 순회하면서 해시 맵에 참가자 이름과 출현 횟수 저장
    for (const name of participant) {
        // 해시 맵에 이름이 이미 있으면 출현 횟수 1 증가
        if (participantMap.has(name)) {
            participantMap.set(name, participantMap.get(name) + 1);
        } else {
            // 해시 맵에 이름이 없으면 출현 횟수 1로 설정
            participantMap.set(name, 1);
        }
    }

    // 완주자 목록을 순회하면서 해시 맵에서 출현 횟수 감소
    for (const name of completion) {
        // 해시 맵에 이름이 있으면 출현 횟수 1 감소
        if (participantMap.has(name)) {
            const count = participantMap.get(name);
            if (count === 1) {
                // 출현 횟수가 0이 되면 해시 맵에서 이름 삭제
                participantMap.delete(name);
            } else {
                // 출현 횟수가 0보다 크면 출현 횟수 1 감소
                participantMap.set(name, count - 1);
            }
        }
    }

    // 해시 맵에 남아 있는 이름 중 출현 횟수가 0보다 큰 이름 반환
    for (const [name, count] of participantMap.entries()) {
        if (count > 0) {
            // 완주하지 않은 참가자 이름 반환
            return name;
        }
    }

    // 결과를 찾을 수 없는 경우 (이론적으로 발생하지 않음)
    return null;
}

// 예제 사용
console.log(findNonFinisher(["leo", "kiki", "eden"], ["eden", "kiki"])); // 출력: "leo"
console.log(findNonFinisher(["marina", "josipa", "nikola", "vinko", "filipa"], ["josipa", "filipa", "marina", "nikola"])); // 출력: "vinko"
console.log(findNonFinisher(["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"])); // 출력: "mislav"

 

||로 기본값 지정

  • falsy 값 : undefined, null, 0, '', NaN
  • 연산자 왼쪽 항의 값이 falsy값이면 오른쪽 항의 값을 반환한다.
let value = undefined; 

let result = value || defaultValue;
console.log(result); // Output: 1

 

활용 예시 : 빈문자열 처리

let str = "";
let defaultStr = "Default String";

let finalStr = str || defaultStr;
console.log(finalStr); // Output: "Default String"

 

for in / for of 반복문

  • for in : 객체 순환
    배열 순환시, 해당 배열의 인덱스값이 나옴.
  • for of : 배열 순환
    객체 순환시, 에러가 나옴.

for in 반복문 예시

객체에 적용

 

배열에 적용

 

for of 반복문 예시

객체에 적용

배열에 적용

728x90