鍍金池/ 問答/PHP/ 如何比較高效的判斷n個(gè)時(shí)間段中,不能存在交集或者子集?

如何比較高效的判斷n個(gè)時(shí)間段中,不能存在交集或者子集?

有n個(gè)時(shí)間段 如下圖所示:

其中每個(gè)時(shí)間段不能與其他時(shí)間段交叉(如 時(shí)間段1:10:00:00-12:00:00,時(shí)間段2:10:30:00-13:00:00),或者不能被包含(如 時(shí)間段1:10:00:00-12:00:00,時(shí)間段2:07:30:00-20:00:00)

時(shí)間段的個(gè)數(shù)沒有限制,前后順序沒有限制。怎么處理比較高效呢?

圖片描述

現(xiàn)在通過sort 排序之后,比較下個(gè)時(shí)間段的開始時(shí)間 是否大于 當(dāng)前時(shí)間段的結(jié)束時(shí)間來處理。是否有更好的辦法解決呢?

回答
編輯回答
拽很帥

你本身的辦法是有問題的,只比較一次會(huì)有漏洞,我有個(gè)想法,你可以試試效率:
將每一組時(shí)間轉(zhuǎn)化為時(shí)間戳,生成 key=時(shí)間戳 value = 數(shù)組號(hào)
統(tǒng)一按照key 排序,檢測(cè)相鄰組號(hào),不連續(xù) 或者 新數(shù)組結(jié)果數(shù)量小于理論值(時(shí)間戳有完全重復(fù),key覆蓋 ))

2017年6月11日 14:21
編輯回答
半心人

排序后再比較這種操作的最后效率取決于你排序的效率了,一般都是O(nlogn),如果還想再快,那只能想O(n)復(fù)雜度的方法了。
方法1:O(n),需要看你的業(yè)務(wù)情況
假如時(shí)間都是半個(gè)小時(shí)一截的,一天24小時(shí),可以分成48個(gè)半個(gè)小時(shí),那么可以用長(zhǎng)度為48的數(shù)組表示這半個(gè)小時(shí)是否被占用,0未占用 1占用,例如a = [1,1,0,...] 就表示00:00 ~ 00:30、00:30 ~ 01:00是占用的。如果你是一個(gè)內(nèi)存吝嗇型的人,那么可以考慮用位運(yùn)算來表示時(shí)間占用情況。
這樣以來,遍歷到每一個(gè)元素直接查數(shù)組看是不是被占用了就行,時(shí)間復(fù)雜度是O(n)

方法2:最壞O(nlogn),二分 + 插入排序,比直接排序稍微好點(diǎn)
維持一個(gè)以開始時(shí)間有序的、無時(shí)間沖突的數(shù)組,判斷一個(gè)時(shí)間段a是否與現(xiàn)有安排沖突,先拿a的開始時(shí)間用二分法找插入位置,找到后與前后元素比較看是否沖突,不沖突的話就插入。這個(gè)算法最壞情況是每次都沒有沖突,這樣會(huì)導(dǎo)致每次都要把元素后挪,所以最壞情況下是O(nlogn),如果安排經(jīng)常沖突的話,這個(gè)算法是不錯(cuò)的。

暫時(shí)只想到這2個(gè)

2017年10月11日 15:50