ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스] h-index (정렬)
    ALGORITHM/PROGRAMMERS 2021. 7. 26. 16:33

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

     

    코딩테스트 연습 - H-Index

    H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다. 어떤 과학자가 발표

    programmers.co.kr

    2021-07-26


    1. 절반을 나눠서 해야한다고 생각했을 때 (너무 복잡하다)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    import java.util.Arrays;
     
    class Solution {
        public int solution(int[] citations) {
            Arrays.sort(citations);
            int index = citations.length % 2 == 0 ? citations.length/2-1 : citations.length/2;
            int h = citations.length - index;
     
            boolean flag = false;
            while(true) {
                if(index >= citations.lengthbreak;
                if(citations[index] >= h) {
                    if(index == 0break;
                    else index--;
                    h++;
                    flag = true;
                } else {
                    if(flag) {
                        h--;
                        break;
                    } else {
                        index++;
                        h = citations.length - index;
                    }
                }
            }
            return h;
        }
    }
    cs

     

     

    #문제풀이

    0. 오름차순 정렬

     

    1. 일단 기준점(index)를 배열 길이의 중앙으로 잡았다. 

     

    2. 그리고 citations 에서 index만큼 뺀 값을 (임시) h값으로 두었다.

     

    3. index값을 길이의 중앙으로 했더니 너무 복잡해졌다. index를 ++만 할 수도 --만 할 수도 없는 상황이어서, 두 가지 경우의 수를 나눠줘야했다. 일단, 이를 위해서 boolean flag를 두었고, 

     

    4. 만약 현재 index의 citations값이 h(citations.length - index)값보다 크거나 같으면, h값의 후보가 될 수 있다. 하지만, 최대값을 구하는 것이므로, 다른 값을 찾기 위해 계속 움직여야한다. 그래서 이렇게 값을 하나 찾았으면 일단 flag = true로 바꿔놓았고, 기준 h값을 ++ 올렸다. 

     

    5. 만약 현재 index의 citations값이 h 값보다 작다면, h값으로 사용할 수가 없다. 이 때 index를 중앙으로 해놓은 것 때문에 또 문제가 생긴다. (1) 값을 이미 찾았는데 최댓값을 찾다가, h값보다 작은 경우를 만난 경우 (2) 값을 한 번도 찾지 못했는데, h값보다 작은 경우이다. 

     

    두 가지 경우를 나눠서 생각했고, (1) 번 (flag == true)의 경우에는 h--를 해주면 마지막으로 찾은 h의 값이므로 함수를 끝낸다.

    (2)번 (flag == false)의 경우에는 index++를 해주어서, (임시)h값을 바꿔주어, 또 다른 값을 찾을 수 있게 만들어주고 반복한다.

     

    이렇게 했을 때, 문제점이 많았다. 일단 생각해야하는 케이스가 많았고 코드도 아래 2번에 비해서 2배 정도가 되버렸다. 

    그래서, index 기준점을 다시 잡고 풀어보았다. 

     

    2. 굳이 절반을 나눠서 할 필요가 없다고 생각했을 때

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import java.util.Arrays;
     
    class Solution {
        public int solution(int[] citations) {
            Arrays.sort(citations);
            int index = 0;
            for(index = citations.length - 1; index >= 0; index--) {
                if(citations[index] < citations.length - index) break;
            }
            return citations.length - index - 1;
        }
    }
    cs

     

    #문제풀이

    index 기준점을 배열의 길이 -1, 즉 맨 끝에 배열로 잡으니깐 훨씬 수월하게 풀 수 있었다.

     

    0. 오름차순 정렬

     

    1. index는 citations.length - 1부터 시작하고, citations[index] 값을 1부터 차례대로 (citations.length - 1) 하나씩 비교 해줬다. 

     

    2. 이 때, citations[index] 값이 citations.length - index 값보다 작으면 즉, h값이라고 부를 수 없는 값이라면 함수를 끝내줬다. 

     

    3. 그렇게 나온 index값이 우리가 찾는 h점의 기준점이 되고, citations.length - index를 해주면 h-index를 찾을 수 있다. 단, for문을 끝내면서 index--를 한 번 더 안 해줘서, 마지막에 return 할 때 -1을 해주었다. 

     

     

    +) 그 외 풀면서 찾은 반례/테스트케이스

    {1, 2, 5, 9, 10}  =>  3

    {0, 0, 0}  =>  0

    {0, 0, 1, 0, 0}  =>  1

    {3, 4, 5, 8, 10}  =>  4

    {11, 22}  =>  2

     

    댓글

Programming Diary