我得到了一个我似乎无法弄清楚的面试问题:鉴于一系列的唠叨。编写一个程序来打印数组中数字的所有排列。输出应按递减顺序排序。例如,对于数组{12,4,66,8,9},输出应为:
9866412
9866124
9846612
...
...
1246689
一个明显的解决方案是置换然后排序,但这将需要n!记忆。我正在寻找能够获取多项式记忆的东西。
我尝试编写递归解决方案,涉及从最大的词典编号开始生成排列:
def compare(x,y):
for i in range(max(len(x), len(y))):
if len(x) <= i:
return compare(x[0], y[i])
elif len(y) <= i:
return compare(x[i], y[0])
elif x[i] < y[i]:
return -1
elif x[i] > y[i]:
return 1
return 0
def print_all_permutations(so_far, num_lst):
if not num_lst:
print so_far
for i in range(len(num_lst)):
cur = num_lst.pop(i)
print_all_permutations(so_far + [str(cur)], num_lst)
num_lst.insert(i, cur)
input_arr = sorted([str(x) for x in [3,31,0]], cmp = compare, reverse=True)
但是对于像以下情况这样的情况就失败了:
['3', '31', '0']
3310
3031
error 3130(['31', '3', '0']) is greater than ['3', '0', '31'](3031)
3130
3103
331
313
答案 0 :(得分:2)
看起来这可以通过按顺序生成数字的排列而不重复来解决,然后对于找到所有匹配值的数字的每个排列来解决。这是python中的一个例子:
def reversed_numerically_ordered_permutations(values):
def permute(digits,prefix):
assert type(digits) is str
if len(digits)==0:
match(prefix,values,[])
last_digit=None
for i in range(len(digits)):
if digits[i]!=last_digit:
permute(digits[0:i]+digits[i+1:],prefix+digits[i])
last_digit=digits[i]
def match(x,values,prefix):
assert type(x) is str
if len(x)==0 and len(values)==0:
print prefix
for i in range(len(values)):
value=values[i]
value_str=str(value)
if x.startswith(value_str):
match(x[len(value_str):],values[0:i]+values[i+1:],prefix+[value])
digits=sorted(''.join(str(x) for x in values),reverse=True)
digits=''.join(digits)
permute(digits,'')
reversed_numerically_ordered_permutations([3,31,0])
输出:
[3, 31, 0]
[31, 3, 0]
[31, 0, 3]
[3, 0, 31]
[0, 3, 31]
[0, 31, 3]
但是,在某些情况下,这可能效率极低。