第 12 场双周赛:5097. 力扣排行榜(TreeSet)

新一轮的「力扣杯」编程大赛即将启动,为了动态显示参赛者的得分数据,需要设计一个排行榜 Leaderboard。

请你帮忙来设计这个 Leaderboard 类,使得它有如下 3 个函数:

  1. addScore(playerId, score)
    • 假如参赛者已经在排行榜上,就给他的当前得分增加 score 点分值并更新排行。
    • 假如该参赛者不在排行榜上,就把他添加到榜单上,并且将分数设置为 score
  2. top(K):返回前 K 名参赛者的 得分总和
  3. reset(playerId):将指定参赛者的成绩清零。题目保证在调用此函数前,该参赛者已有成绩,并且在榜单上。

请注意,在初始状态下,排行榜是空的。

 

示例 1:

输入: 
["Leaderboard","addScore","addScore","addScore","addScore","addScore","top","reset","reset","addScore","top"]
[[],[1,73],[2,56],[3,39],[4,51],[5,4],[1],[1],[2],[2,51],[3]]
输出:
[null,null,null,null,null,null,73,null,null,null,141]

解释: 
Leaderboard leaderboard = new Leaderboard ();
leaderboard.addScore(1,73);   // leaderboard = [[1,73]];
leaderboard.addScore(2,56);   // leaderboard = [[1,73],[2,56]];
leaderboard.addScore(3,39);   // leaderboard = [[1,73],[2,56],[3,39]];
leaderboard.addScore(4,51);   // leaderboard = [[1,73],[2,56],[3,39],[4,51]];
leaderboard.addScore(5,4);    // leaderboard = [[1,73],[2,56],[3,39],[4,51],[5,4]];
leaderboard.top(1);           // returns 73;
leaderboard.reset(1);         // leaderboard = [[2,56],[3,39],[4,51],[5,4]];
leaderboard.reset(2);         // leaderboard = [[3,39],[4,51],[5,4]];
leaderboard.addScore(2,51);   // leaderboard = [[2,51],[3,39],[4,51],[5,4]];
leaderboard.top(3);           // returns 141 = 51 + 51 + 39;

 

提示:

  • 1 <= playerId, K <= 10000
  • 题目保证 K 小于或等于当前参赛者的数量
  • 1 <= score <= 100
  • 最多进行 1000 次函数调用

 

思路:一道辣鸡题,想着用TreeSet进行解决,结果出现了一堆问题,也算是重新认识了TreeSet,存一下以防下次出现相同的问题吧,这里想说set自带的equals真坑,最好自己手写。。。

class node implements Comparable<node>{
	int x,y;
	public node(int x,int y) {
		this.x=x;
		this.y=y;
	}
	@Override
	public int compareTo(node o) {
		// TODO 自动生成的方法存根
		if(y==o.y)
			return x-o.x;
		return o.y-y;
	}
	
	public boolean equals(Object obj) {
		if(obj instanceof node) {
			node Node =(node)obj;
			if(x==Node.x && y==Node.y)
				return true;
		}
		return false;
	}
	
	@SuppressWarnings("deprecation")
	public int hashCode() {
		return new Integer(x).hashCode()+new Integer(y).hashCode();
	}
}
class Leaderboard {

	private Set<node> st;
	private Map<Integer,Integer>map;
    public Leaderboard() {
    	st=new TreeSet<>();
    	map=new HashMap<>();
    }
    
    public void addScore(int playerId, int score) {
        	if(!map.containsKey(playerId)) {
        		map.put(playerId, score);
        		st.add(new node(playerId,score));
        	}
        	else {
        		int tmp=map.get(playerId);
        		st.remove(new node(playerId,tmp));
        		map.put(playerId, tmp+score);
        		st.add(new node(playerId,map.get(playerId)));
        	}
    }
    
    public int top(int K) {
        int num=0,sum=0;
        Iterator<node> it=st.iterator();
        while(num<K && it.hasNext()) {
        	sum+=it.next().y;
        	num++;
        }
        return sum;
    }
    
    public void reset(int playerId) {
    	node tmp=new node(playerId,map.get(playerId));
    	st.remove(tmp);
        map.remove(playerId);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值