我正在设计一个前5名击球手的棒球联赛记分牌。我使用TreeMap
将 player_name 用作value
,将Player
用作key
。
Map<Player, String> players = new TreeMap<>(Collections.reverseOrder());
Player
课程按照联赛中的得分自然排序
compare(this.leagueRuns, otherPlayer.leagueRuns)
leagueRuns
会更新,并且TOP 5 Batsmen记分牌也应相应更改。以下是更新玩家联赛并重新插入TreeMap
的代码。更新后,将检索并显示来自Map的TOP 5条目。
public void updateRuns(String playerName, int runsScored) {
Iterator<Entry<Player, String>> playersEntries = players.entrySet().iterator();
Player player = null;
while (playersEntries.hasNext()) {
Entry<Player, String> currentPlayer = playersEntries.next();
if (currentPlayer.getValue().equalsIgnoreCase(playerName)) {
player = currentPlayer.getKey();
}
}
players.remove(player);
player.addRuns(runsScored);
players.put(player, player.getName());
}
一切正常,但我有以下顾虑:
Player
进行排序,我在Key
中将其用作TreeMap
。但必须遍历整个Map
以查找正在更新的Player
。因此,时间复杂度从O(1)降低到O(n)。更糟糕的是因为我必须删除Player
,更新它并重新插入否则更改将不会生效。因此O(n + logn)
。有没有办法按照自然顺序对Player
进行排序,也可以在O(1)中搜索。我想重新插入是不可避免的。leagueRuns
时,都必须重新订购整个TreeMap
。你认为创造一个单独的TOP 5 Batsmen的最小堆可以解决这个问题,这是一个可行的想法。答案 0 :(得分:2)
你应该支持2种结构:
因此更新记分板将为O(log(N)):
Map<String, Player> players;
SortedSet<Player> scoreboard;
public void updateRuns(String playerName, int runsScored) {
Player player = players.get(playerName);
if (player == null) {
player = new Player(playerName, runsScored);
} else {
scorepoard.remove(player);
player.addRuns(runsScored);
}
scoreboard.add(player);
}
如果你使Player类不可修改(首选方式),你将获得相同的O(log(N)):
public void updateRuns(String playerName, int runsScored) {
Player player = players.remove(playerName);
if (player == null) {
player = new Player(playerName, runsScored);
} else {
scorepoard.remove(player);
player = new Player(playerName, player.getRuns() + runsScored);
}
players.put(playerName, player);
scoreboard.add(player);
}