計算時間重疊次數的優化

2021-10-19 22:39:46 字數 2225 閱讀 6853

由於專案中直播間實際會控制最大人數在6人,而直播間存續時長一般也不會超過24小時,所以開始時偷了點懶,採用暴力方式處理。

暴力解法

顯然這是乙個n²複雜度的演算法,如果每乙個時間段,都會被其他所有時間段分割,那麼輸入的n個時間段最終會產生2n-1個時間段,所以實際上會比n²還要耗時,開始以為偷懶的暴力方法,事實證明,一點也不省事兒,實現**如下

type timesectionlist struct

type timesection struct

func

(this *timesectionlist)

mergets

(us, ue int64

)else

if e > t.s && e < t.e

) t.overlap, t.e = t.overlap+

1, e

return s, t.s,0,

0}else

if e == t.e

}else

if s > t.s

) this.tss =

(this.tss,

×ection

) t.s, t.e, t.overlap = s, e, t.overlap+

1return0,

0,0,

0}else

if s < t.e && e > t.e

) t.overlap++

t.s = s

return0,

0, t.e, e

}else

if e == t.e

) t.s = s

t.overlap++

return0,

0,0,

0}}else

else

if e < t.e

) t.overlap++

t.e = e

return0,

0,0,

0}else

if e == t.e }}

this.tss =

(this.tss,

×ection

)return0,

0,0,

0}hs, ht, ts, te :=

check

(us, ue)

if hs !=

0if ts !=0}

func

(this *timesectionlist)

getmaxduration

() timesecion

else

if ts.overlap == max }}

return timesecion

}

除了效能不高外,實際的實現過程,需要考慮九種情況,包含各種起止時間重疊的情形。好在業務規模有限,也勉強撐著了。

優化思路

雖然這個功能不就就被下線了,但是心裡有塊石頭始終放不下,實在是對n²複雜度不滿意。

一開始考慮能否使用查詢樹來解決,但是由於時間段包含起始結束時間兩個元素,所以這將會是乙個定製的查詢樹,實現起來比暴力方法複雜,所以放棄了這個思路。

某日突然發覺,似乎棧非常適合用來解決這個問題。開始時間對應壓棧,離開時間對應彈棧,棧內元素最多時,不就是想要的結果嗎?

重複上一動作,lend被清空,此時n=2,stime=9:18,etime=9:20,至此演算法結束

優化分析

綜合來看,排序部分為nlogn的複雜度,出入棧操作為n,整體複雜度從暴力演算法的n²下降到nlogn,實際專案應用中,起止時間儲存在資料庫中,如果庫中對在時間列上有b+tree索引,則排序部分複雜度可以下降為n,那麼整體的複雜度就是線性複雜度了。

排序部分**就不寫了,下面是棧操作**

func

maxtimeduration

(start, end [

]time.time)

(int

, time.time, time.time)

else

if l == max

}else}}

forlen

(start)

>

0else

if s.

after

(e)}

closetime

(end[0]

)return max, ts, te

}

關於sql語句中,統計時間重疊和時間不重疊

我們在開發過程中總會遇到這樣的情況,一行資料中,有id 組 開始時間 結束時間。但是開始時間和結束時間肯定會出現時間重疊問題,比如說下面這種情況。我們先找出時間重疊的公式 可以發現 公式如下 a.alarm type id b.alarm type id and a.start time b.sto...

KMP演算法計算出現次數(包含重疊部分)

kmp演算法 返回模式串在文字串 現的次數。例如 abdabdababdab 中 abdab 在 0,4 3,7 8,12 出現,則返回3 主要的改動在kmp函式中的while迴圈 include using namespace std void getnext const char ps,int ...

關於遞迴次數的計算

有這樣乙個題目 遞迴函式 1 int x intn 2 7else 811 計算x x 8 遞迴呼叫次數。大多數可能覺得這是乙個很簡單的題目,的確很簡單。但是要想在沒有編譯器的情況下正確的算出這個遞迴 呼叫次數其實還是需要點耐心.x x 8 我們先計算x 8 我們用count 0計數遞迴呼叫次數 1...