我需要一種算法,它可以將排列中的運行映射到單個數字,但也會減少後續數字。減少排列
因此,運行是按排序和按序排列的序列中的一組數字。在列表中,1; 2; 3; 5; 6; 4有兩次運行,1; 2; 3和5; 6。我想用一個數字來代替它們,這是最小的,所以如果在移除運行之後,我們有4個元素的置換,置換使用數字1 ... 4.在上面,我們必須減少兩次運行。第一次運行將是1,4,轉換爲2,[5; 6]轉換爲3,以保持第二個標準。如果我對減少的排列進行排序,然後從映射中展開內部元素,然後對原始排列進行排序,我將得到相同的結果。由此產生的排列不應該有任何運行。
例如(我已經強調了運行):
(1;2;3;4;5;6) => 1 //Mappings: 1->1;2;3;4;5;6
(2;3;4);1;(5;6) => 2 1 3 // Mappings: 2->2;3;4, and 3->5;6
(3;4);(1;2);(5;6) => 2 1 3 // Mappings: 2->3;4, and 1->1;2 and 3->5;6
現在,我越過清單,然後列出名單,分組的運行。真正的第二部分是制定一個乾淨解決方案的難點。我想到了天真的做法,好奇的是,如果任何人有一些聰明的把戲,可以做得更好,那麼我的,我在像O(2n + n日誌n),
- 替換運行head元素並將該數據插入散列表(用於可恢復性)
- 排序以創建映射到缺失數字及其排序索引。 [1; 6; 5; 4]會輸出[(1,1);(4,2);(5,3);(6,4)]
- 用步驟2中創建的映射替換步驟1中的列表並更新散列表以進行翻譯。運行
通過一個例子,再次:
step 1: replace runs with the head element of the run and inserting data into a hash table [1;3;4;2;5;6;] -> [1;3;2;5] step 2: sort array to create map [1235], so we know that, in the previous array, 1 maps to 1, 2 to 2, 3 to 3, 4 to 5. step 3: do above translation on array from step one. [1;3;2;4]
如果我排序這個置換和重建:[1; 2; 3; 4],3-> 3; 4和4-> 5; 6我得到,1; 2; 3; 4; 5; 6。還排序。
我正在使用列表,所以功能方法將是首選。沒有必要的代碼。當然,所有的想法都是值得歡迎的。
編輯:
mweerden:
目前尚不清楚對我有什麼對測繪精確的條件。爲什麼不允許爲N次運行的置換生成置換[1,2,...,N]?你似乎更喜歡將跑步映射到跑步中的一個數字,但是(因爲這並非總是可行),你似乎允許一些自由。 -
我不喜歡跑步映射到運行中的一些(看上面!),但我需要保持一個訂購。置換[1; 2; 3 ... N] 爲一次運行,因此可以進一步降低。這就是爲什麼它是無效的。這個順序在另一個算法的進一步操作中很重要,但是單個元素可以在最後擴展以挽救原始排列。
你可以更深入地解釋你的基本算法嗎?我很難明白你想要做什麼。特別是我不跟隨你的介紹如何解釋你的例子。 – 2009-01-26 16:48:06
我同意,你的算法不是很清楚。這是困擾我的第三條線。而你的更長時間的例子則更沒有意義。考慮更簡單的例子? – 2009-01-26 17:11:21