优化以下hackerrank程序

优化以下hackerrank程序,c,algorithm,data-structures,linked-list,C,Algorithm,Data Structures,Linked List,我想优化我编写的以下代码,以便它能够通过hackerrank问题中的所有测试用例。它目前可以工作,但在某些情况下由于超时而失败。你能指导我如何在不改变概念的情况下优化代码吗 问题 爱丽丝正在玩一款街机游戏,想爬上排行榜的顶端。 你能帮她跟踪她的排名,因为她击败了每一个级别?该游戏使用密集排名,因此其排行榜如下: •得分最高的玩家在排行榜上排名第二 •得分相等的玩家获得相同的排名编号,下一个玩家获得紧随其后的排名编号 例如,四名玩家的得分分别为100、90、90和80。这些玩家的级别分别为1、2、

我想优化我编写的以下代码,以便它能够通过hackerrank问题中的所有测试用例。它目前可以工作,但在某些情况下由于超时而失败。你能指导我如何在不改变概念的情况下优化代码吗

问题

爱丽丝正在玩一款街机游戏,想爬上排行榜的顶端。 你能帮她跟踪她的排名,因为她击败了每一个级别?该游戏使用密集排名,因此其排行榜如下:

•得分最高的玩家在排行榜上排名第二

•得分相等的玩家获得相同的排名编号,下一个玩家获得紧随其后的排名编号

例如,四名玩家的得分分别为100、90、90和80。这些玩家的级别分别为1、2、2和3

当Alice开始比赛时,排行榜上已经有人了。Alice参加
m
级别的比赛,我们表示她通过每个级别后的总分。完成每个级别后,Alice想知道她当前的排名

您将获得一组单调递减的排行榜分数,以及另一组Alice在游戏每个级别的累积分数。您必须打印整数:整数应表示通过每个级别后Alice的当前排名

输入格式:

  • 第一行包含一个整数
    n
    ,表示已经在排行榜上的玩家数量
  • 下一行包含
    n
    空格分隔的整数,用于描述分数的各个值
  • 下一行包含一个整数
    m
    ,表示级别数
  • 最后一行包含
    m
    空格分隔的整数,描述每个播放器的各自值
输出格式:

打印整数。整数应表示通过每个级别后Alice的排名

输入

7
100 100 50 40 40 20 10
4
5 25 50 120
6
4
2
1
输出

7
100 100 50 40 40 20 10
4
5 25 50 120
6
4
2
1
这是我的密码:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct player {
    int rank;
    int score;
};

struct node {
    struct player data;
    struct node *next;
};

int main() {
    int n, i, m, temp, count = 1, x;
    struct node *ptr, *head;
    head = (struct node *)malloc(sizeof(struct node));
    ptr = head;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%d", &x);
        ptr->data.score = x;
        if (x < temp)
            count++;
        ptr->data.rank = count;
        temp = ptr->data.score;
        ptr->next = (struct node *)malloc(sizeof(struct node));
        ptr = ptr->next;
    }
    ptr = NULL;
    ptr = head;
    scanf("%d", &m);
    for (i = 0; i < m; i++) {
        scanf(" %d", &x);
        while (x < ptr->data.score)
            ptr = ptr->next;
        if (ptr->next == NULL)
            ptr->data.rank = count + 1;
        printf("%d\n", ptr->data.rank);
        ptr = head;
    }
    return 0;
}
#包括
#包括
#包括
#包括
结构播放器{
整数秩;
智力得分;
};
结构节点{
结构播放器数据;
结构节点*下一步;
};
int main(){
int n,i,m,temp,count=1,x;
结构节点*ptr,*head;
head=(结构节点*)malloc(sizeof(结构节点));
ptr=头部;
scanf(“%d”和“&n”);
对于(i=0;idata.score=x;
如果(xdata.rank=计数;
temp=ptr->data.score;
ptr->next=(结构节点*)malloc(sizeof(结构节点));
ptr=ptr->next;
}
ptr=NULL;
ptr=头部;
scanf(“%d”、&m);
对于(i=0;idata.score)
ptr=ptr->next;
如果(ptr->next==NULL)
ptr->data.rank=count+1;
printf(“%d\n”,ptr->data.rank);
ptr=头部;
}
返回0;
}

问题在于,每次为Alice取排名时,我都从一开始就遍历链表。对此可能进行的优化是什么?

反转代表排行榜的列表,使排行榜单调递增。如果排行榜是按这种方式排序的,则只需从最后一个位置开始遍历排行榜。例如,对于您的示例输入:

10/5    20/4    40/3    40/3     50/2     100/1     100/1           leaderboard
5               25               50                           120   score
6               4                2                            1     pos
作为伪代码:

node n = leaderboard.reverse().head

foreach score in scorelist:
    while n != null and n.score > score
        n = n.next

    if n == null:
        print 1
    else:
        print n.pos - 1

这是因为基于
score[i]
在排行榜中的位置(
l[j]
),我们知道
score[i+1]
必须在
l[j+x]
的位置,反向排行榜中的
x>0

代码中存在未定义的行为,因为您没有初始化
temp
变量:第一次比较
如果(x
有未定义的行为,那么
计数可能会错误地增加

Paul的方法是将复杂性从O(N2)降低到O(N)的一个非常好的解决方案

以下是修改后的代码:

#include <stdio.h>
#include <stdlib.h>

struct node {
    int rank;
    int score;
    struct node *next;
};

int main(void) {
    int n, i, m, last = 0, rank = 1, x;
    struct node *ptr, *head = NULL;
    if (scanf("%d", &n) != 1)
        return 1;
    for (i = 0; i < n; i++) {
        ptr = malloc(sizeof(*ptr));
        if (ptr == NULL)
            return 1;
        if (scanf("%d", &ptr->score) != 1)
            return 1;
        if (ptr->score < last)
            rank++;
        ptr->rank = rank;
        last = ptr->score;
        ptr->next = head;
        head = ptr;
    }
    if (scanf("%d", &m) != 1)
        return 1;
    for (ptr = head, i = 0; i < m; i++) {
        if (scanf(" %d", &x) != 1)
            return 1;
        while (ptr && x > ptr->score)
            ptr = ptr->next;
        if (ptr == NULL)
            rank = 1;
        else
        if (x == ptr->score)
            rank = ptr->rank;
        else
            rank = ptr->rank + 1;
        printf("%d\n", rank);
    }
    return 0;
}
#包括
#包括
结构节点{
整数秩;
智力得分;
结构节点*下一步;
};
内部主(空){
int n,i,m,last=0,秩=1,x;
结构节点*ptr,*head=NULL;
如果(scanf(“%d”,&n)!=1)
返回1;
对于(i=0;i分数)!=1)
返回1;
如果(ptr->分数<上次)
排名++;
ptr->rank=rank;
最后一次=ptr->得分;
ptr->next=头部;
水头=ptr;
}
如果(scanf(“%d”,&m)!=1)
返回1;
对于(ptr=head,i=0;iptr->score)
ptr=ptr->next;
如果(ptr==NULL)
秩=1;
其他的
如果(x==ptr->分数)
等级=ptr->rank;
其他的
秩=ptr->秩+1;
printf(“%d\n”,秩);
}
返回0;
}

这些问题的重点不一定只是编写高效的代码,而是找到一个智能算法。这是你必须解决的真正挑战,我知道。我试过了,但我无法找到一个有效的程序,使用链表来解决我的问题。所以,如果你能帮我一点忙,那就太好了。:)使用堆栈可以解决这个问题,但我只想使用链表。残酷地说,如果你不能解决它,请尝试另一个挑战。这个网站不是“解决我的挑战”网站,但对于C的特定问题,我会继续尝试其他挑战,但这不是我在stackoverflow中发布的真正目的,是吗?我的答案是,如果我能解决问题,我会直接提交给Hackerrank,