leetcode 621 任務排程器
阿新 • • 發佈:2018-12-05
題目描述:CPU執行任務,每個任務需要1個單位的執行時間,兩個相同任務之間需要有n個時間間隔的冷卻時間,求CPU執行這些任務最少需要多少時間。
例子:
輸入:AAABBBCCCCC, n=2(其中A,B,C表示三種不同的任務)
輸出:13
解釋:CPU執行可以為CABCABCABC_ _ C (_表示CPU待命狀態)
兩種解法。
第一種解法:用優先佇列,在n個時間內,按照任務出現次數優先輸出執行次數多的任務。
第二種解法:經過一定的數學分析,發現CPU執行任務的時間只取決於出現次數最多的任務次數。
兩種解法的比較:
優先佇列方法比較直觀,執行效率略低。
數學分析法需要前期作一定的數學分析。執行效率高,但分析過程有時難以想到,並且需要考慮特殊情況(n=0)
1. 優先佇列
def leastInterval(self, tasks, n): """
優先佇列 :type tasks: List[str] :type n: int :rtype: int """ n+=1 ans=0 d=collections.Counter(tasks) heap=[-c for c in d.values()] heapq.heapify(heap) while heap: stack=[] cnt=0 for _ in range(n): if heap: c=heapq.heappop(heap) cnt+=1 if c<-1: stack.append(c+1) for item in stack: heapq.heappush(heap,item) ans+=heap and n or cnt # if heap: n else: cnt return ans
2. 數學分析
可以簡化為,挑出出現次數最多的任務F,假設其出現次數為M次,那麼最終的結果就是在M個任務F之間插入n個時間段。
因此對於前n-1個F,一定有(M-1)*(n+1)個執行次數。
對於最後1個F,可能存在的情況是多個任務都出現了F次,
比如 CCCAAABBB, n=2
假設選定出現次數最多的任務F為C,那麼前2個週期為C_ _ C _ _
後面的一個週期為CAB,即再加上出現次數為最大頻次的任務個數。
還有一種特殊情況:每個任務都出現了1次。那麼此時執行任務的最少次數就是任務列表的長度。
def leastInterval(self, tasks, n): """ :type tasks: List[str] :type n: int :rtype: int """ d=collections.Counter(tasks) v=d.values() M = max(d.values()) ans = (M-1)*(n+1) for i in v: if i==M: ans+=1 return max(ans,len(tasks)) #解決n=0的特殊情況