您现在的位置是:首页 >技术杂谈 >leetcode:相对名次(详解)网站首页技术杂谈

leetcode:相对名次(详解)

Artiel 2024-06-17 10:18:43
简介leetcode:相对名次(详解)

前言:内容包括-题目,代码实现,大致思路,代码解读

目录

题目:

代码实现:

大致思路:

 代码解读:

part 1:开辟返回数组

part 2:score数组的每个元素及其下标构成一个整体元素

part 3:对arr数组倒序排序(从大到小)

part 3:分配名次


题目:

给你一个长度为 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函数:将格式化的数据转成字符串

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。