230209 Codility OddOccurrencesInArray(javascript)

샨티(shanti)·2023년 2월 8일
0

코딩테스트

목록 보기
32/35
post-custom-banner

매일 매일 하루 한 문제씩.
꾸준히 이어가는 코딩테스트 풀이 기록 ✅

오늘은 프로그래머스 문제를 한 30분정도? 보다가 결국 알고리즘을 알아야 풀 수 있는 문제인 것 같아서 시간이 더 들기 전에 빠른 GG 치고 Codility 문제로 넘어왔다.

Codility 문제가 쉽다기 보다는 어제의 맥락에서 이어 풀 수 있는 것이라 그랬는데...
오늘도 역시나 답은 통과했는데 performance 측면에서 확 떨어지는 모습을 보였다.

정말 지난-한 시간을 보내는 느낌이다.
해야지 하면서도 잘 안되는데. 그래도 또 해야지 하며 두들기고 있는 나.
어쨌든, 통과된 다른분의 코드를 참고해서 익혀보았다.
reduce가 빠른걸까, 이 분의 로직이 빠른걸까.

나도 2개의 코드를 작성해보았는데 첫번째는 효율성이 떨어질 줄 알았고 그래도 두번째는 통과할 줄 알았는데 통과가 안돼서 약간 의외였..

우선 performace를 통과하지 못한 코드 2개, 그리고 맨 마지막에 다른 분 코드를 참고하여 작성한 내용을 추가한다. 사실 다른 코드를 참고했던 부분은 eslint가 미친듯이 빨간줄을 쳐 놓은 상태라 이게 맞는건가 싶긴 한데. reduce를 객체로 사용하는 법, 그리고 그 객체를 마치 배열처럼 iterate 하는 부분은 숙지하고 있어야 할 것 같다.


문제 링크

OddOccurrencesInArray


Javascript

첫 번째 효율성 낮은 코드의 로직은 이렇다.
어떤 요소(element)들이 들어가있는지를 확인하기 위해 set을 하나 만들고.
그 set의 요소들을 하나씩 꺼내가면서 배열을 filter하여 배열의 길이가 홀수인 경우 set에서 꺼낸 요소를 return.

이미 배열을 filter하는 부분에서 시간 초과가 날 것 같았는데 역시나 그랬다.

function solution(A) {
  const uniqueSetOfElement = new Set(A);
  let answer = 0;

  const keys = [...uniqueSetOfElement.keys()];

  for (let i = 0; i < keys.length; i += 1) {
    const filteredArray = A.filter((value) => value === keys[i]);
    if (filteredArray.length % 2 !== 0) {
      answer = keys[i];
      break;
    }
  }
  return answer;
}

두 번째 코드는 shift로 모든 배열을 탐색하는 것이었다.
그래도 배열을 모두 탐색하지만 딱 한번 linear하게 탐색하는 것이기도 하고, 중간에 얼마든지 조건에 맞으면 탈출할 수 있기에 시간 초과가 나지 않을 것이라 생각했는데... 좀 당황시렵긴 했다.

function solution(A) {

  const sortedArray = A.sort((a, b) => a - b);
  let answer = 0;
  let count = 0;

  while (true) {
    const popedElement = sortedArray.shift();
    count += 1;

    if (sortedArray[0] !== popedElement) {
      if (count % 2 === 0) {
        count = 0;
        continue;
      }

      if (count % 2 !== 0) {
        answer = popedElement;
        break;
      }
    }
  }

  return answer;
}

마지막으로 다른 분의 코드를 참고한 내용.
reduce를 사용했고 객체를 만들어 element:element의 갯수 요소가 들어가도록 한 것이다.

따지고보면 이 역시도 배열을 한번 쭉- 한바퀴는 도는 것 아닌가... 흠...
바로 위에 코드에서 shift가 문제였을까? pop이면 괜찮았을까? 궁금하다.

function solution(A) {
  const total = A.reduce((count, num) => {
    count[num] = count[num] ? count[num] + 1 : 1;
    return count;
  }, {});

  for (key in total) {
    if (total[key] % 2 === 1) {
      return Number(key);
    }
  }

  return 0;
}

오늘은 문제 자체가 어려운 건 아니었는데 자꾸 performance 측면에서 떨어지는 게 좀 답답하다. ㅎㅎ 면접에서 들은 얘기가 있어서 그런가.

꺾이는 마음을 다시 부여잡는게 쉽지 않은데 그래도 또 오늘 새롭게 배운걸 토대로 더 나은 걸 만들기 위해 노력하자.

profile
가벼운 사진, 그렇지 못한 글
post-custom-banner

0개의 댓글