先上题目:
两个思路:
1. 暴力法。对输入的数组nums[]中的每一个元素都计算它在数组中的大小顺序rank,然后根据rank来计算输出,用switch case语句直接搞定。nums[]有n个元素,每个元素都需要与数组中的其他元素比较一次,时间复杂度是O(n^2) 测试通过时间116ms 代码见下:
int getDigit(int n);
void itoa(int val, char* s, int digit);
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
char** findRelativeRanks(int* nums, int numsSize, int* returnSize) {
char** res;
int i, j;
int rank, digit;
*returnSize = numsSize;
res = (char**)malloc(sizeof(char*)*numsSize);
for(i = 0; i < numsSize; i++) {
rank = 1;
for(j = 0; j < numsSize; j++) {
if(i == j) {
continue;
}
else {
if(nums[i] < nums[j]) {
rank++;
}
}
}
switch(rank) {
case 1:
res[i] = (char*)malloc(sizeof(char)*(strlen("Gold Medal")+1));
strcpy(res[i], "Gold Medal");
break;
case 2:
res[i] = (char*)malloc(sizeof(char)*(strlen("Silver Medal")+1));
strcpy(res[i], "Silver Medal");
break;
case 3:
res[i] = (char*)malloc(sizeof(char)*(strlen("Bronze Medal")+1));
strcpy(res[i], "Bronze Medal");
break;
default:
digit = getDigit(rank);
res[i] = (char*)malloc(sizeof(char)*(digit+1));
res[i][digit] = '\0';
itoa(rank, res[i], digit);
break;
}
}
return res;
}
int getDigit(int n) {
int d = 0;
while(n) {
n/=10;
d++;
}
return d;
}
void itoa(int val, char* s, int digit) {
int i, r;
for(i = 0; i < digit; i++) {
r = val%10;
s[digit-1-i] = r+'0';
val/=10;
}
}
2. 额外利用一个数组scores[],记录下nums[]中出现的所有分数及其对应的位置,即scores[]的key是nums[i],value是对应的下标i。这种方法需要先找出nums[]中的最大值以确定scores[]的大小,赋值好scores[]之后,逆序判断各个元素的rank 找出最大值和赋值scores[]数组耗时O(n),测试通过时间6ms 代码见下:
int getDigit(int n);
void itoa(int val, char* s, int digit);
char* getString(int n);
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
char** findRelativeRanks(int* nums, int numsSize, int* returnSize) {
char** res;
int i, max;
int rank;
int* scores;
*returnSize = numsSize;
res = (char**)malloc(sizeof(char*)*numsSize);
// find max nums[]
max = nums[0];
for(i = 1; i < numsSize; i++) {
if(max < nums[i]) {
max = nums[i];
}
}
// construct scores[]
scores = (int*)malloc(sizeof(int)*(max+1));
memset(scores, -1, sizeof(int)*(max+1));
for(i = 0; i < numsSize; i++) {
scores[nums[i]] = i;
}
// calculate rank
rank = 1;
for(i = max; i >= 0; i--) {
if(scores[i] != -1) {
res[scores[i]] = getString(rank);
rank++;
}
}
free(scores);
return res;
}
char* getString(int n) {
char* s;
int d;
switch(n) {
case 1:
s = (char*)malloc(sizeof(char)*(strlen("Gold Medal")+1));
strcpy(s, "Gold Medal");
break;
case 2:
s = (char*)malloc(sizeof(char)*(strlen("Silver Medal")+1));
strcpy(s, "Silver Medal");
break;
case 3:
s = (char*)malloc(sizeof(char)*(strlen("Bronze Medal")+1));
strcpy(s, "Bronze Medal");
break;
default:
d = getDigit(n);
s = (char*)malloc(sizeof(char)*(d+1));
s[d] = '\0';
itoa(n, s, d);
break;
}
return s;
}
int getDigit(int n) {
int d = 0;
while(n) {
n/=10;
d++;
}
return d;
}
void itoa(int val, char* s, int digit) {
int i, r;
for(i = 0; i < digit; i++) {
r = val%10;
s[digit-1-i] = r+'0';
val/=10;
}
}