给定一组整数,编写一个程序来打印数组中数字的所有排列。输出应按非递增顺序排序。
例如,对于数组{12, 4, 66, 8, 9}
,输出应为:
9866412
9866124
9846612
....
....
1246689
我考虑过生成所有排列,同时将它们插入BST
,然后在BST
上执行反向排序。
这似乎非常低效,因为我存储了排列,我们能做得更好吗?
答案 0 :(得分:0)
c ++ STL:
vector arr = ..
排序(arr.begin(),arr.end())
做
{
//在此处理您的数据
} while(next_permutation(arr.begin(),arr.end());
这可以在O(2 ^ n)中为您做到。在内部通过有效的交换方式实现。如果您需要进一步的帮助,请告诉我
答案 1 :(得分:0)
首先使用数字对数字进行排序(可能将它们转换为字符串)。对于instnace,9大于11.您可以为此实现简单的插入排序。
所以现在你有一个按这种方式排序的数字列表(比如说n1,n2,n3,n4)。
使用此列表,您可以轻松获得已排序的所有排列,合并列表中的元素,并在生成过程中交换最后一个排列。
即:n1n2n3n4,n1n2n4n3,n1n3n2n4 ......等等。
实施例:
4,11,76,100
100,11,4,66
10011476,10011764,10041176 ......
关于复杂性:排序需要k*n^2
(使用插入排序,您可以节省内存,因为它已就位),k
是数字的最长大小(示例中为3,由数字给出) 100),因为如果有相似的数字,你需要比较他们的所有数字(如10000和100001)。然后,您只需要生成所有排列,这需要n!
。最终时间复杂度为O(n!)
,不需要额外的空间。
答案 2 :(得分:0)
如果您使用的是Python,模块itertools有一个解决方案,请参阅here。
如果您可以访问Knuth的计算机编程艺术第4卷,第4章,它有许多解决方案,递归和迭代。
此外,RosettaCode提供多种语言的解决方案,请参阅here。 Fortran 77解决方案是迭代的,您可以对其进行调整以满足您的需求,或者以任何语言进行翻译。它以递增的词典顺序提供解决方案。
现在,如果我不明白你的要求,你需要按递减顺序解决方案,考虑连接数字串的排序。可能难以直接实施,因为例如(100,99,999)小于(99,100,999),小于(999,99,100):“10099999”< “99100999”< “99999100”。您不能简单地使用数字列表的词典顺序。但是,按字典顺序生成排列非常容易。
答案 3 :(得分:0)
为了推理,我会递归地执行:
a
,您执行以下操作:
a
,并获取一个包含少于原始数组的元素的数组。生成递归这个新获得的数组的所有排列,并在每个递归生成的排列前面添加a
。这种方法基本上与您在搜索树中存储排列(但不是二进制)的想法相对应,并枚举它们。但是,它使用递归堆栈来执行此操作,并且不存储整个树。
另一种方法可能会使用factorial number system。这可以用于正确枚举排列。所以你可以“只计算倒数并重建相应的排列”。