[英]Efficient algorithm for comparing elements in the same list
我有一個帶有開始和結束時間的BaseBallGame對象列表。 我需要確保每個游戲都在單獨的時間進行,以便用戶可以觀看所有游戲的實時流。
我有O(n^2)
的算法。 我至少需要使其為nlog(n)
。 有人可以給我指點一下如何改善實施性能嗎?
public class GameTime {
public static Boolean canViewAll(Collection<BaseBallGame> baseBallGames) {
List<BaseBallGame> games_list = (List<BaseBallGame>) baseBallGames;
boolean isOverlap = false;
for (int i = 0; i < games_list(); i++) {
for (int j = i + 1; j < games_list(); j++) {
Date startA = games_list(i).getStart();
Date endA = games_list(i).getEnd();
Date startB = games_list(j).getStart();
Date endB = games_list(j).getEnd();
boolean isStartABeforeEndB = (startA.compareTo(endB)) < 0;
boolean isEndAAfterStartB = (endA.compareTo(startB)) > 0;
boolean isCurrentPairOverlap = false;
isCurrentPairOverlap = isStartABeforeEndB && isEndAAfterStartB;
if (isCurrentPairOverlap) {
isOverlap = true;
}
}
}
return !isOverlap;
}
boolean overlap(Date start1, Date end1, Date start2, Date end2){
return start1.getTime() <= end2.getTime() && start2.getTime() <= end1.getTime();
}
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("y-M-d H:m");
ArrayList<BaseBallGame> baseBallGames = new ArrayList<BaseBallGame>();
baseBallGames.add(new BaseBallGame(sdf.parse("2015-01-01 20:00"), sdf.parse("2015-01-01 21:30")));
baseBallGames.add(new BaseBallGame(sdf.parse("2015-01-01 21:30"), sdf.parse("2015-01-01 23:00")));
baseBallGames.add(new BaseBallGame(sdf.parse("2015-01-01 23:10"), sdf.parse("2015-01-01 23:30")));
System.out.println(GameTime.canViewAll(baseBallGames));
}
}
class BaseBallGame {
private Date start, end;
public BaseBallGame(Date start, Date end) {
this.start = start;
this.end = end;
}
public Date getStart() {
return this.start;
}
public Date getEnd() {
return this.end;
}
}
如果要使用比較器對列表進行排序,然后對列表進行一次迭代,看看是否有任何時間重疊該怎么辦?
Java數組排序算法 :java.util.Arrays對實現Comparable或使用Comparator的對象使用mergesort。
合並排序算法為平均/最佳/最壞情況nlog(n)
。 然后,一次迭代將可以忽略不計。
有很多排序算法,您可以在代碼中實現它們。 網站上的以下排序算法已實現,並且還顯示了時間復雜度。
https://www.toptal.com/developers/sorting-algorithms
Quicksort和Quicksort 3方式分區是nlogn算法。
如果您只想檢查是否存在沖突,則可以嘗試
Set<BaseBallGame> baseBallGameSet = new HashSet<BaseBallGame>(games_list);
if(baseBallGameSet.size < games_list.size)
// Clash exists.
您可以在@thebenman建議之前將其視為優化。
適應此問題的最有效算法是間隔搜索樹。 您有開始時間和結束時間,這意味着您有間隔。 一旦您的游戲開始,並且如果不與其他游戲的時間重疊,則將其放入樹中。 當您開始一個新游戲時,請放置該游戲時間,如果該時間與上一游戲的時間重疊,則樹會報告,因為它具有介入作用。
無需每次都檢查新游戲,只需將間隔放入樹中,如果該間隔與其他間隔相交,則樹數據結構將自動檢測並報告該間隔。 這種插入和刪除算法的時間復雜度~logN
,這非常有效。 如果您有R個交集,則復雜度將為~RlogN
,其中R
是交集數。
您也可以在這里觀看羅伯特·塞奇威克的視頻。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.