Leetcode - 506. Relative Ranks

숲사람·2022년 4월 14일
0

멘타트 훈련

목록 보기
6/237

문제

주어진 배열의 각 요소에 해당하는 랭킹(값 크기순)을 출력하라. (단 1,2,3위는 메달이름, 4위부터는 순위를 문자열로 저장.)

Input: score = [10,3,8,9,4]
Output: ["Gold Medal","5","Bronze Medal","Silver Medal","4"]
Explanation: The placements are [1st, 5th, 3rd, 2nd, 4th].

문제 바로가기 : https://leetcode.com/problems/relative-ranks/

해결 O(N logN)

더 좋은 해결책이 있을것 같으나, N번 heap_push(logN), N번 heap_pop(logN)하여, 총 O(N*logN)으로 해결하였다.

int를 string으로 저장하는 방법은 sprintf()를 사용하면 된다.sprintf(ret[tmp.idx], "%d", rank);

#define HEAP_MAX    10001

struct ath {
    int score;
    int idx;
};
struct pq {
    struct ath heap[HEAP_MAX];
    int heap_size;
};
struct pq *q;

void swap(struct ath arr[], int a, int b)
{
    struct ath temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

void heapify_up(struct ath arr[], int curr_idx)
{
    int p_idx = (curr_idx - 1) / 2;
    
    if (curr_idx < 1)
        return;
    if (arr[curr_idx].score > arr[p_idx].score) {
        swap(arr, curr_idx, p_idx);
        heapify_up(arr, p_idx);
    }
}

void heap_push(struct ath arr[], int score, int idx)
{
    arr[q->heap_size].score = score;
    arr[q->heap_size].idx = idx;
    q->heap_size++;
    heapify_up(arr, q->heap_size - 1);
}

void heapify_down(struct ath arr[], int p_idx, int size)
{
    int largest = p_idx;
    int l_idx = p_idx * 2 + 1;
    int r_idx = p_idx * 2 + 2;
    
    if (l_idx < size && arr[l_idx].score > arr[largest].score)
        largest = l_idx;
    if (r_idx < size && arr[r_idx].score > arr[largest].score)
        largest = r_idx;
    if (largest != p_idx) {
        swap(arr, largest, p_idx);
        heapify_down(arr, largest, size);
    }
}

struct ath heap_pop(struct ath arr[])
{
    struct ath ret = arr[0];
    q->heap_size--;
    swap(arr, 0, q->heap_size);
    heapify_down(arr, 0, q->heap_size);
    return ret;
}
void print_heap(struct ath arr[])
{
    for (int i = 0; i < q->heap_size; i++)
        printf("%d ", arr[i].score);
    printf("\n");
}
char medal[4][15] = {
    "", "Gold Medal", "Silver Medal", "Bronze Medal"    
};
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
char ** findRelativeRanks(int* score, int scoreSize, int* returnSize){
    *returnSize = scoreSize;
    char **ret = (char **)malloc(sizeof(char *) * scoreSize);
    q = (struct pq *)malloc(sizeof(struct pq));
    memset(q, 0, sizeof(struct pq));

    for (int i = 0; i < scoreSize; i++) // O(n logn)
        heap_push(q->heap, score[i], i);
    
    for (int rank = 1; rank <= scoreSize; rank++) { // O(n logn)
        struct ath tmp = heap_pop(q->heap);
        if (rank <= 3) {
            ret[tmp.idx] = (char *)malloc(sizeof(char) * 15);
            strcpy(ret[tmp.idx], medal[rank]);
        } else {
            ret[tmp.idx] = (char *)malloc(sizeof(char) * 6);
            sprintf(ret[tmp.idx], "%d", rank);
        }
    }
    return ret;
}
profile
기록 & 정리 아카이브 용도 (보다 완성된 글은 http://soopsaram.com/documentudy)

0개의 댓글