簡體   English   中英

用於比較同一列表中元素的高效算法

[英]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;
    } 

}

您正在描述活動選擇問題

  1. 根據結束時間對列表進行排序。
  2. 迭代列表並檢查A[i+1]的開始時間是否大於A[i]的結束時間。

並且由於涉及排序,因此它具有O(n log n)

如果要使用比較器對列表進行排序,然后對列表進行一次迭代,看看是否有任何時間重疊該怎么辦?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM