프로그래머스

Winney·2021년 3월 10일
0
post-thumbnail

정말 오랜만에 프로그래머스를 풀었다. 마지막 블로그 이후 띄엄띄엄하다가 어느순간 안 풀었는데 계속 신경이 쓰여서 오늘!!! 완전 각 잡고 다시 풀어보았다.

완주하지 못 한 선수

문제 설명
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항

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

입출력 예시는 밑의 링크에서 확인!!

출처: https://programmers.co.kr/learn/courses/30/lessons/42576

첫번째 작성

function solution(participant, completion) {
  const participants = {};
  
  for(let key of participant) {
    if(!participants[key]) {
      participants[key] = 1;
    } else if(participants[key]) {
      participants[key] += 1
    }
  };
  
  for(let key of completion) {
    if(participants[key]) {
      participants[key] -= 1;
    }
  }

  for(let person in participants) {
    if(participants[person] > 0) {
      return person;
    }
  }
};

생각의 흐름으로 작성한 풀이이다. 문제만 읽고 어떻게 풀어야할지 전혀 감을 못 잡다가 프로그래머스에 해시 키워드로 문제가 되어 있어서 Object[key] = value만 생각하고 풀었다.
문제는 해결했지만 다른 사람들 풀이를 보니 유난히 문제 풀이 방법이 길어보이고 특히 for...in이 반복문으로 쓰는 것을 권장하지 않는다는 댓글을 보고 다시 작성해보았다.

두번째 작성

function solution(participant, completion) {
   participant.sort()
   completion.sort()
  
  for(let i = 0; i < participant.length; i++) {
    if(participant[i] !== completion[i]) {
      return participant.slice(i, i+1)[0]
    }
  }
};

아주 많이 줄어들었다. 일단 sort()를 쓰는 것은 옛날에 이 문제를 봤을 때 생각하고 지나갔었는데 이번에 다른 사람 풀이를 보면서 기억이 나서 썼다.
그리고 for...in문을 사용하지 않았다! 댓글대로 for...in문을 사용하지 않으니 70ms -> 50ms로 속도가 줄었다.
하지만 정렬된 참가자와 완주자의 각 위치를 비교해서 완주하지 못 한 사람만 잘라내다 보니 결과가 배열로 나왔다. 이렇게 ['leo']!!
하지만 문제에서 요구한 결과 타입은 string으로 한 명만 결과로 도출되도록 되어있었다. 그래서 index [0]을 마지막에 적어뒀지만 뭔가 하드코딩같아보여서 별로이다.

다른 사람 풀이

function solution(participant, completion) {
    participant.sort();
    completion.sort();
  
    for(let i in participant) {
        if(completion.includes(participant[i]) == false) 
        return participant[i];
      
        completion.splice(completion.indexOf(participant[i]), 1);
    };
};

다른 분 풀이에서 주석처리한 부분만을 가져왔다. 왜냐하면 그 분이 주석처리 하지 않은 방법에는 for...in문이 사용되었기 때문이다.
나는 slice를 사용했지만 여기에는 splice가 사용되었다. 차이는 새 배열을 반환하느냐 여부이다.
그리고 이번에 splice가 속도가 느린 메서드라는 사실을 알았다. 유일하게 시간초과로 통과하지 못 했는데 제출 당시와 현재의 프로그래머스가 다르기 때문이 아닐까 싶다. 앞으로 가급적이면 slice를 쓰는 방향이 좋다는 것을 알았다.

profile
프론트엔드 엔지니어

1개의 댓글

comment-user-thumbnail
2021년 4월 4일

재미있네요.
혹시 이 문제가 프로그래머스 레벨 몇 정도일까요?

답글 달기