我需要一种算法,它可以将排列中的运行映射到单个数字,但也会减少后续数字。减少排列
因此,运行是按排序和按序排列的序列中的一组数字。在列表中,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