您现在的位置是:首页 >技术杂谈 >leetcode:相对名次(详解)网站首页技术杂谈
leetcode:相对名次(详解)
前言:内容包括-题目,代码实现,大致思路,代码解读
目录
part 2:score数组的每个元素及其下标构成一个整体元素
题目:
给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 "Gold Medal" 。
名次第 2 的运动员获银牌 "Silver Medal" 。
名次第 3 的运动员获铜牌 "Bronze Medal" 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。
使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
示例 1:
输入:score = [5,4,3,2,1]
输出:["Gold Medal","Silver Medal","Bronze Medal","4","5"]
解释:名次为 [1st, 2nd, 3rd, 4th, 5th] 。
示例 2:
输入:score = [10,3,8,9,4]
输出:["Gold Medal","5","Bronze Medal","Silver Medal","4"]
解释:名次为 [1st, 5th, 3rd, 2nd, 4th] 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/relative-ranks
代码实现:
int cmp(const void* e1, const void* e2)
{
return *((int*)e2) - *((int*)e1);
}
char ** findRelativeRanks(int* score, int scoreSize, int* returnSize)
{
char** ret = (char**)malloc(scoreSize * sizeof(char*));
int i = 0;
for (i = 0; i < scoreSize; i++)
{
ret[i] = (char*)malloc(13 * sizeof(char));
}
//或者 int(*arr)[2] = (int(*)[2])malloc(scoreSize * sizeof( arr[0]));
int arr[scoreSize][2];
for (i = 0; i < scoreSize; i++)
{
arr[i][0] = score[i];
arr[i][1] = i;
}
qsort(arr, scoreSize, sizeof(arr[0]), cmp);
char* arr2[] = { "Gold Medal" ,"Silver Medal" ,"Bronze Medal" };
for (i = 0; i < scoreSize; i++)
{
if (i < 3)
{
strcpy(ret[arr[i][1]], arr2[i]);
}
else
{
sprintf(ret[arr[i][1]], "%d", i + 1);
}
}
*returnSize = scoreSize;
return ret;
}
大致思路:
1 将score数组的每个元素和它的下标存放在一起,则一个元素和它的下标构成一个一维数组
所以scoreSize个元素和其下标存放在一起,就构成scoreSize个一维数组,即一个二维数组
二维数组的行是scoreSize,列是2
以 [10,3,8,9,4]为例:
2 按照倒序对arr数组的每个元素(每个元素都是一个一维数组)进行排序,使用qsort函数
排序好后,前3个元素就是前3名(下标是0,1,2)
3 遍历排序后的arr数组,前3个元素分别对应金牌,银牌,铜牌 ,后面的元素获得的名次是它的下标+1
由于arr数组的每个元素都是一个一维数组,这个一维数组的第二个空间存放的就是原来在score数组中的下标,那么排序后的arr数组每个元素获得的名次需要存入原下标所对应的空间中去。
代码解读:
part 1:开辟返回数组
char** ret = (char**)malloc(scoreSize * sizeof(char*));
int i = 0;
for (i = 0; i < scoreSize; i++)
{
ret[i] = (char*)malloc(13 * sizeof(char));
}
返回数组的每个元素是char*类型
每个元素都是一个字符数组,用于存储字符串
part 2:score数组的每个元素及其下标构成一个整体元素
//或者 int(*arr)[2] = (int(*)[2])malloc(scoreSize * sizeof( arr[0]));
int arr[scoreSize][2];
for (i = 0; i < scoreSize; i++)
{
arr[i][0] = score[i];
arr[i][1] = i;
}
score数组一个元素及其下标构成一个整体元素,这个整体元素即一个一维数组
一维数组有两个空间,第一个空间存放score,第二个空间存放原下标
共可以构成scoreSize个一维数组,即一个二维数组arr
二维数组的行是scoreSize行,列是2列
二维数组空间的开辟:
法1:可以直接定义int arr[scoreSize][2];
法2:malloc开辟
int(*arr)[2] = (int(*)[2])malloc(scoreSize * sizeof( arr[0]));
//二维数组的每个元素类型是一维数组,malloc会返回开辟空间的起始地址,二维数组的起始地址,即二维数组首元素的地址,即一维数组的地址,即一维数组指针
一个一维数组所占空间的大小:sizeof(数组名)
arr[i]是二维数组arr每个元素(一维数组)的数组名,数组名[i]就可以对一维数组的每个空间进行访问
part 3:对arr数组倒序排序(从大到小)
qsort(arr, scoreSize, sizeof(arr[0]), cmp);
使用qsort函数排序,比较两个元素大小的函数cmp需要自己设计
int cmp(const void* e1, const void* e2)
{
return *((int*)e2) - *((int*)e1);//按照倒序排列
//将e1和e2强制转换成int*类型,这样便能对一维数组中的每个元素访问
//*((int*)e2)得到一维数组中的第一个元素,即分数score
}
arr的每个元素都是一维数组,我们排序的依据是比较一维数组中的第一个元素
part 3:分配名次
char* arr2[] = { "Gold Medal" ,"Silver Medal" ,"Bronze Medal" };
for (i = 0; i < scoreSize; i++)
{
if (i < 3)
{
strcpy(ret[arr[i][1]], arr2[i]);//金牌,银牌,铜牌的分配
}
else
{
sprintf(ret[arr[i][1]], "%d", i + 1);//普通名次的分配,名次是下标+1
}
}
*returnSize = scoreSize;
return ret;
从大到小排序后的arr数组:
sprintf函数:将格式化的数据转成字符串