Leetcode 506. Relative Ranks

先上题目:

两个思路:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值