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;
}