Leetcode506. 相对名次(排序+哈希)

https://leetcode-cn.com/problems/relative-ranks/

给出 N 名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌。前三名运动员将会被分别授予 “金牌”,“银牌” 和“ 铜牌”(“Gold Medal”, “Silver Medal”, “Bronze Medal”)。

(注:分数越高的选手,排名越靠前。)
示例 1:
输入: [5, 4, 3, 2, 1]
输出: [“Gold Medal”, “Silver Medal”, “Bronze Medal”, “4”, “5”]
解释: 前三名运动员的成绩为前三高的,因此将会分别被授予 “金牌”,“银牌”和“铜牌” (“Gold Medal”, “Silver Medal” and “Bronze Medal”).
余下的两名运动员,我们只需要通过他们的成绩计算将其相对名次即可。
提示:
N 是一个正整数并且不会超过 10000。
所有运动员的成绩都不相同。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
/*
    思路:先将成绩排个序, 然后将(成绩-名次)键值对存入哈希表中,再依次遍历原数组,输出名次,将前三名转换为相应的字符
*/

void quick_sort(int *nums, int start, int end){
    if(start >= end)
        return;
    
    int i = start; 
    int j = end;
    while(i < j){
        while(nums[j] < nums[start] && i < j)  j--;
        while(nums[i] > nums[start] && i < j)  i++;
        
        if(i < j){
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    }
    // 交换基准值
    int tmp = nums[start];
    nums[start] = nums[i];
    nums[i] = tmp;
    
    quick_sort(nums, start, i - 1);
    quick_sort(nums, i + 1, end);  
}


typedef struct HASHKV{
    int key; // score
    int value; // order
}Hashkv;

typedef struct HASHTAB{
    Hashkv *elems;
    int count;
}Hashtab;

void init_hash(Hashtab *ht, int count){
    ht->elems = (Hashkv *)calloc(count,sizeof(Hashkv));
    ht->count = count;
}

int Hash(Hashtab *ht, int key){
    return key % ht->count;
}

void insert_hash(Hashtab *ht, Hashkv kv){
    int addr = Hash(ht, kv.key);
    
    while(ht->elems[addr].key != 0) {// 处理冲突
        addr = (addr + 1) % ht->count;
    }
    ht->elems[addr].key = kv.key;
    ht->elems[addr].value = kv.value;
}

int find_hash(Hashtab *ht, int key){
    int addr = Hash(ht, key);
    
    while(ht->elems[addr].key != key) {// 处理冲突
        addr = (addr + 1) % ht->count;
        //此处未判断找不到的情况,因为不会找不到,若判断了,则超出时间限制,尴尬了
    }
    return ht->elems[addr].value;
}


char ** findRelativeRanks(int* nums, int numsSize, int* returnSize){
    // 备份原数组
    int *o_nums = (int *)malloc(numsSize * sizeof(int));
    int i = 0;
    for(; i < numsSize; i++){
        o_nums[i] = nums[i];
    }
    
    // 将o_nums排序 (需要从大到小排序)
    quick_sort(o_nums, 0, numsSize - 1);
    
    // 将排序的键值对插入哈希表
    Hashtab *ht = (Hashtab *)calloc(1, sizeof(Hashtab));
    init_hash(ht, numsSize);
    for(i = 0; i < numsSize; i++){
        Hashkv kv = {o_nums[i], i + 1};
        insert_hash(ht, kv);
    }
    
    //创建返回数组
    char **ret = (char **)calloc(numsSize, sizeof(char *));
    for(i = 0; i < numsSize; i++){
        ret[i] = (char *)calloc(1024, sizeof(char));
    }
    
    
    //用原数组查找哈希表,取名次值
    for(i = 0; i < numsSize; i++){
        int order = find_hash(ht, nums[i]);
        //printf("order is %d\n", order);
        switch (order)
        {
            case 1:
                snprintf(ret[i], 16, "Gold Medal");
                break;
            case 2:
                snprintf(ret[i], 16, "Silver Medal");
                break; 
            case 3:
                snprintf(ret[i], 16, "Bronze Medal");
                break;
            default:
                snprintf(ret[i], 16, "%d", order);
                break;
        }
    }
    
    *returnSize = numsSize;
    return ret;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值