[英]How can I solve this problem, and what kind of algorithm is the appropriate on if any to solve it
[英]Not sure what kind of algorithm this problem requires / what data structure (Printer Queue problem)
這幾乎是一個打印機隊列問題。
輸入樣例:
6 0
1 1 9 1 1 1
第一行=兩個數字,第一個是打印機作業的數量,第二個是作業在隊列中的位置
第二行=每個作業的優先級。 列出的第一個數字是第一個工作的優先級,依此類推。 數字越大,優先級越高。
打印機無限期地運行此循環:
輸出直到打印機完成作業為止的分鍾數。
問題在於位置很重要。 因此,正如您在測試用例中所看到的,您的工作在隊列中的第一個,這意味着它不是優先級最高的,因此它被移到了后面,第二個工作也被移到了后面,並且您的工作將在5分鍾后完成打印。
我認為LinkedList最適合此操作,但是您必須跟蹤最高優先級,該優先級是動態更改的。 PriorityQueue的問題在於,元素是根據某些Comparator插入的,而我的結構的初始順序將基於位置。 另外,您不能添加到PriorityQueue的后面。
因此,我有點想知道要使用哪種結構,或者這個問題是否涉及任何結構。
編輯:我寫道@MinosIllyrien答案是正確的,但事實並非如此。 但是,我認為我可以解決問題。 如果您認為我失敗了,請隨時發表評論。
這是我自己的解釋:
假設您有三類人:
在一個公平的世界中,會發生什么? 首先,通過MITY,然后通過AIAY,輪到您在隊列中的前面,現在輪到您了(無論有多少LITY:公平地說,但不要太多)。
但是在您的世界中,每次MITY通過時,他/她都會更改AIAY的順序。 直到最后一個MITY通過都沒關系。 如果他/她在您之前,那沒問題。 但是,如果他/她在您后面,您和他之前的所有AIAY都將移到后方。 因此,這之后的AIAY在您之前,而AIAY在您之前的位置仍然在您之前。 因此,您之后剩下的唯一AIAY是您和最后一個MITY之間的AIAY。
編輯:問題是MITY的順序:它們不是按位置(在MinosIllyrien答案中的問題)排序,而是按優先級和位置排序。 上面的部分沒有缺陷,並且保持不變。
如果需要輸出排序的作業,則不需要特定的數據結構。 這是一種具有簡單鏈表(或兩個數組列表)的算法:一個用於存儲作業,一個用於標記已執行的作業)
假設作業列表不為空。
步驟1的時間復雜度是O(n log n),然后是Ps中每個P的O(n),即O(n log n + n * Ps.size)。 如果您知道優先級的邊界,則第1步僅是帶有桶分類的O(n),因此整個序列的復雜度為O(n * Ps.size)。
如果您實際上想模擬打印機的行為,我認為正確的方法是使用一個鏈表(或一個數組加上一個整數,以便在您反復遍歷它時跟蹤您的當前位置) 加上優先級隊列。 每當發現鏈表頂部的值與優先級隊列中的最高值匹配時,便將其從兩個隊列中刪除。 這種方法需要最壞情況下的O ( n 2 )時間。
但是,如果您只想查找分鍾數,則可以在最壞情況下的O ( n log m )時間進行操作,其中n是作業總數, m是不同優先級的數目。 (M≤N,這樣也有最壞情況下為O(n log n)的時間。)這里有一種方法:
TreeMap<Integer, ArrayList<Integer>>
將每個優先級值映射到具有該優先級的作業隊列索引列表。
int lastPos = -1
和int numJobsCompleted = 0
。 lastPos
; 否則,采用最大的工作隊列索引(=列表元素)。 無論哪種情況,都將lastPos
更新lastPos
作業隊列索引,並更新numJobsCompleted
以添加作業隊列索引列表的大小。
lastPos
指向作業隊列中最新完成的項的索引; 這樣我們就可以處理下一個優先級的作業,該作業從索引lastPos+1
開始,到索引lastPos-1
結束(當然,在n處環繞)。 lastPos
和我們感興趣的作業的索引之間的作業索引的數量,並相應地更新numJobsCompleted
。 這可以通過線性搜索(最壞情況O ( n ))或二進制搜索(最壞情況O (log n ))來完成。 這是錯誤的-我在底部寫下了原因:
[[瀏覽列表。 在索引之前,將具有相同優先級或高於您的優先級的每個元素都算作索引。 在索引之后,僅將優先級比您的元素嚴格高的元素算為一個,直到最后一個優先級更高的索引為止。 在該索引之后,繼續將優先級與您相同的所有元素都計為一個。 這樣可以為您提供要在元素之前打印的元素數量,因此請為您自己的元素增加一分鍾的時間。
我希望這有幫助。
編輯:
澄清一下:讓我們根據優先級重命名隊列中的所有元素。 l較低,e等於,h較高。 w是通緝文件。 問題中的順序將是:
w e h e e e
我們從計算w之前的e和h的數目開始,因為它們將在w之前打印。 (e被移動到w之前的隊列的后面, h被首先處理。)在此示例中, w之前沒有元素,因此我們將其計數為0。
在w之后,我們僅計算h ,因為它們被移到了隊列的最前面。 在此示例中只有1個。
最后,我們數數E'后W¯¯是最后小時后(如果有任何小時后W),因為W是后面移動這些電子的。 一共有3個,所以總共我們之前有4個打印作業。 添加我們自己的打印作業,我們總共可以得到5個作業/分鍾。
為此,我們需要遍歷列表兩次,一次查找最后一個h ,一次進行計數。
編輯:
舉一個新的例子。 讓我們假設我們的隊列是2、2',9、8、2、1、7,其中2'是我們的文檔。
發生的第一件事是前2個發送到隊列的后面,然后是2':
2 2' 9 8 2 1 7
2' 9 8 2 1 7 2
9 8 2 1 7 2 2'
然后打印9和8,剩下2、1、7、2、2'。 現在將2和1發送到后面。
2 1 7 2 2'
1 7 2 2' 2
7 2 2' 2 1
並打印7。 我們剩下2、2',2、1。這些按順序打印,而2'作為整體的第5個元素打印。
如果遵循上述步驟,我們將其重寫為:
2 2 9 8 2 1 7
e w h h e l h
直到w為止,我們統計0次出現的h和1次發生的e 。 這是2個,稍后在我們自己之前打印。 在w之后,我們在最后一個h之后計算3 h和0 e 。 這意味着將在我們自己之前打印三個元素(9、8和7),而不會打印e和l (2和1)。
總共,我們算出了4個印刷在我們自己之前的元素,我們的印刷是第5個。
我沒有考慮過要素可能要經過幾輪。 當較高優先級的工作按降序排列時,上述情況成立,但是反正例是(ru'h)指出的(1',2,1,3)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.