[英]Count number of intervals containing another interval?
給定兩個列表,每個列表包含N個間隔(數字行的子集),每個間隔具有起始點和端點的形式。 一個列表中有多少對這些間隔包含來自另一個列表的間隔?
例如:
如果列表A是{(1,7), (2,9)}
,列表B是{(3,6), (5,8)}
那么A的間隔包含B中的間隔的對數將是3對:
(1,7),(3,6)
(2,9)(3,6)
(2,9)(5,8)
目標是射擊O(n log n)。
我的算法目前首先按x坐標排序,然后將其作為一個列表。 然后按y坐標對列表進行排序,並計算兩個列表之間的反轉。 但我的問題是為什么這有效? 任何見解將不勝感激。
我現在可視化的方式是以下幾何方式(其中每個線的交點都是num反轉的計數):
注意:我不確定如何在列表列表中檢查反轉。 只是試圖獲得一個給出O(n log n)的方法。 如果有任何其他方法樂於聽取建議。
如果您決定嘗試使用樹/網格方法,我將解釋它是如何工作的。 對於您的任務,您不需要2D,而是需要一維間隔圖甚至網格。 讓我們選擇網格,因為它更清晰。
假設你的對是從1到100的整數。那么你可以買一個大小為100的數組。數組中的每個單元都包含空集(有序列表)。 見下圖:
現在我們開始在網格中添加間隔。 我們在2,9之間的所有網格單元中的1,7和2之間的所有網格銷售中添加1(1,2是ID,我們在每個插入的間隔增加1,以這種方式插入是低效的但是這可以是固定的)。
現在我們如何檢查B的間隔? 我們只從第一個單元格中獲取每個ID,並檢查它是否也在第二個單元格中。 由於單元格已設置,因此檢查采用O(log n)。 在最壞的情況下我們需要n O(log n)運算來檢查B中的一個區間在A內的重疊區間計數。
這可以擴展為使用間隔映射而不是網格(如果數字不是小整數)。 此外,如果您在A中有固定數量的間隔,並且沒有內存要求,那么如果我們用數組替換集合,則O(logN)可以變為O(1)。
我將回答第一個問題,為什么帶有反演的解決方案有效。 首先,我會澄清一件事。 您不應該計算所有反轉(線的交叉點),而只計算A列表中的元素和B列表中的元素之間的相交。 在你的例子中沒有區別,但我們假設A = {(1,7), (2,5)}
和B = {(3,6), (5,8)}
。 如果我們在你的例子中可視化這些情況,那么將有2個交叉點,但我們正在尋找的只有1對,即(1,7),(3,6)。
現在讓我們假設我們有2個區間: I1=(x1,y1)
和I2=(x2,y2)
。 I2
包含在I1
。 這意味着x1 <= x2
且y1 >= y2
。 現在,如果按x排序間隔列表,則I1
將始終位於I2
之前。 類似地,如果您按y選擇間隔列表,則I1
將始終位於I2
之后。 它還豆,如果我們連接I1
, I2
在第一個列表與I1
, I2
在第二個列表,則線必須跨越。
但是,我們假設x1 <= x2
且y1 < y2
。 現在I1
將在I2
之前的第一個和第二個列表中。 如果我們連接I1
, I2
與第一列表I1
, I2
在第二個列表,則線將永遠不會交叉。 同樣的情況是x1 > x2
和y1 >= y2
以下是這些案例的可視化:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.