[코테] H-Index (정렬)

ekil·2026년 4월 21일

코딩테스트

목록 보기
13/15

H-Index (정렬)

2026.4.20, 2026.4.21 (작성일: 2026.4.22)

https://school.programmers.co.kr/learn/courses/30/lessons/42747

핵심 개념

  • 문제에서 차용된 H-Index라는 개념을 어떻게 구할지 접근하는 것 자체
  • 내가 작성한 조건의 엣지케이스가 언제 발생하는지 떠올리는 것

내 풀이

function solution(citations) {
    const sorted = citations.sort((a, b) => b - a);
    const answer = sorted.findIndex((e, i) => e < i + 1);
    
    // 마지막 e도 i + 1보다 크거나 같으면 index = -1
    // 모든 논문이 전체 논문 개수 이상으로 인용되었으므로, hIndex = 전체 논문 개수
    return answer === - 1 ? citations.length : answer;
}

개선된 풀이

function solution(citations) {
    const sorted = citations.sort((a, b) => b - a);
    const answer = sorted.filter((e, i) => e >= i + 1).length;
    
    return answer;
}

핵심 차이

  • 내 풀이는 조건을 만족하지 않는 첫 번째 순간을 찾으므로, 조건 충족 즉시 멈춘다. 그러나 findIndex 결과가 -1인 경우에 대한 예외 처리가 필요
  • 개선된 풀이는 제출 후 다른 사람의 풀이를 보다가 발견한 건데, 조건을 만족하는 것의 개수를 세는 방식으로 항상 전체를 순회한다. 데이터가 엄청 크다면 비효율적일 수도 있겠지만 예외 처리가 필요 없어서 코드가 간결하다.
  • 그래서 개선된 풀이가 모든 상황에서 "개선된" 풀이라고 볼 순 없지만, 반례를 찾느라 조금 헤맸던 걸 생각하면 코딩테스트에선 '개선'이라 볼 수 있을지도..

막혔던 포인트

  • H-Index를 어떻게 구할 것인가?
    처음엔 주어진 인용 횟수의 평균을 구하고 그것이 H-Index일 수 있는지 체크하고, 아니라면 더 작은 쪽 혹은 더 큰쪽으로 다시 평균을 구해 동일한 비교를 계속하는 방식을 생각했다. 그런데 그런 식으론 구할 수 없었다!
    잘 모르겠어서 문제에 첨부된 H-Index 위키백과 링크에 들어가 찬찬히 읽었다. 아래 설명을 읽고 아하 했다.

    공식적으로, f가 각 출판물에 대한 인용 횟수에 해당하는 함수라고 할 때, h-index를 다음과 같이 계산합니다: 먼저 f의 값을 가장 큰 값부터 가장 작은 값으로 정렬합니다. 그런 다음, f가 위치(h라고 부르는 이 위치)보다 크거나 같은 마지막 위치를 찾습니다. 예를 들어, 5편의 출판물 A, B, C, D, E가 각각 10, 8, 5, 4, 3번의 인용을 받았다면, h-index는 4입니다. 왜냐하면 4번째 출판물이 4번의 인용을 받았고, 5번째는 3번만 인용을 받았기 때문입니다. 반면에, 같은 출판물이 25, 8, 5, 3, 3번의 인용을 받았다면, 인덱스는 3입니다. 즉, 3번째 위치입니다. 왜냐하면 4번째 논문이 겨우 3번만 인용을 받았기 때문입니다.

    주어진 citations 배열을 내림차순으로 정렬하고, elementindex를 비교하면 되겠구나.
    그 비교는 element >= index + 1을 만족하는 순간까지이니까,
    그것을 만족하지 않는 첫번째 순간의 index를 찾으면 되겠다, 생각했다. (만족하지 않는 첫번째 index의 직전 elementindex + 1 = 만족하지 않는 첫번째 elementindex - 1 + 1)
  • 다른 말로 정리하면, 배열 속 요소 element가 자신의 index + 1보다 크거나 같은 케이스 중 가장 큰 index + 1이 H-Index인 것이다.
  • 그렇게 했는데 1개 케이스에서 실패했다. 이번에도 반례인가! 하면서 이전 문제에서와 같이 모든 요소가 0인 경우를 고민했으나 이번엔 그게 반례가 아니었다.
  • 이럴 땐 내가 쓴 코드를 자세히 뜯어보는 것도 힌트가 될 수 있음을 깨달았다. 딱 봐도 예외 케이스가 생길 부분이 어디인가? findIndex에서 -1을 반환하는 경우다. 그런 상황은 언제 발생하나? 배열의 모든 요소가 e < i +1을 만족하지 않을 때, 즉 모든 element가 자신의 index + 1보다 크거나 같을 때이다.
    예를 들어 citations = [1, 2, 3, 4]라면, H-Index는 -1이 아니라 4가 되어야 한다. 그리고 그것은 전체 논문의 개수 = citations.length와 같다.
  • 발상을 조금 전환하면, 배열을 내림차순 정렬한 뒤 element가 자신의 index + 1보다 크거나 같은 요소만 남기고 그것의 length를 구하면 그게 H-Index와 같다.

풀면서 찾은 개념

  • findIndex가 받는 콜백함수에서 index도 인자에 있는지 체크했다.

다음에 비슷한 문제 만나면

  • H-Index 위키백과를 읽으면서 접근법을 알아낸 걸 볼 때, 가능하면 다양한 예시를 접해야 접근법이 명확해지는데, 문제 이해도가 낮을 땐 정확한 예시를 떠올리기 어렵다. 이건 여러 문제를 풀어보며 능력치를 길러보자.
  • 엣지케이스, 반례를 찾을 땐 문제의 제약 조건 + 내가 작성한 코드를 같이 뜯어보자. 특히 의심되는 지점을 좀더 파보자.
  • 찾기 어렵다면 엣지케이스를 고려하지 않아도 되는 접근법이 있을지 생각을 전환해보는 것도 방법이다.
profile
좋아하는 일을 잘함으로써 먹고살고 싶은 프론트엔드 개발자입니다.

0개의 댓글