프로그래머스 완주하지 못한 선수 JS 풀이

조병근·2023년 3월 23일
0

알고리즘

목록 보기
2/3

프로그래머스 level1 완주하지 못한 선수

문제를 보자마자 생각한 해법은 이랬다.
1. 완주자와 완주하지 못한 사람들 이름을 key로 갖는 객체를 생성하고, 해당 key값을 갖는 사람 수를 count
2. 두 객체의 이름별 value값 비교
3. 다른 값이 나오는 이름이 answer

function solution(participant, completion) {
  var answer = "";
  let partiObj = new Object();
  let compObj = new Object();
  let fail = [];
  let part = participant.filter((v) => !completion.includes(v));
  answer = part[0];
  participant.map((v) => {
    partiObj[v] ? partiObj[v]++ : (partiObj[v] = 1);
    if (partiObj[v] > 1) {
      part.push(v);
    }
  });
  completion.map((v) => {
    compObj[v] ? compObj[v]++ : (compObj[v] = 1);
  });
  part.map((v) => {
    part.map((v) => {
      if (partiObj[v] - compObj[v] === 1) {
        answer = v;
      }
    });
  });
  return answer;
}

정확성은 통과하나, 효율성 부문에서 통과하지 못했다는 점이 문제였다.
내 알고리즘을 보면 모든 이름을 탐색하기 때문에 적어도 2N번 만큼 탐색해야된다는 것이었다.

그래서 고민하던 중 다른 해법을 보게 되었다.

function solution(participant, completion) {
  var answer = "";

  completion[completion.length] = "";

  var arr1 = participant.sort();
  var arr2 = completion.sort();

  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] !== arr2[i]) {
      answer = arr1[i];
    }
  }

  return answer;
}

1) completion 배열이 participant 배열 길이보다 1짧기때문에 "" 하나 더해준다.
2) 두 배열을 정렬 후 비교

코드 길이도 확 줄었고, 무조건 N번만 탐색하기 때문에 내 알고리즘과 같은 O(N)의 알고리즘이더라도 훨씬 효율적이었다.

var solution = (participant, completion) =>
  participant.find(
    (name) => !completion[name]--,
    completion.map((name) => (completion[name] = (completion[name] | 0) + 1))
  );

완주자 배열을 {이름:완주자배열에 등장하는 횟수}로 맵핑하고, 그 맵에 참가자 이름 하나씩 넣어서 찾아볼때마다 횟수 떨어뜨려서 횟수 0 나오는 걸 찾는 함수이다.

마지막 코드는 어떤 고수분이 정리하신 코드.. 이렇게까지 작성할 수 있는 날이 올때까지 노력해야겠다.

profile
노력하면 못할 일이 없다

0개의 댓글