[英]Writing an n choose k function using recursion: returning the value and number of recursive calls made as a tuple
[英]Print n choose k combination algorithm using recursion
这一定是一个经典的面试问题,但是,我在理解它时遇到了问题。
下面是我在Python中的实现,如果您运行它,它只会打印ab, ac, ad
。 它不会达到'b' (bc, bd)
级别。
def Print_nCk (the_list, k, str_builder, used):
if len(str_builder) == k:
print str_builder
return
else:
for i in xrange(len(the_list)):
if used[i] !=True:
str_builder+=the_list[i]
used[i] = True
Print_nCk(the_list, k, str_builder, used)
str_builder = str_builder[:-1]
Print_nCk(['a','b','c','d'], 2, "",[False,False,False,False])
当以上行通过时,正确的答案是ab,ac,ad,bc,bd,cd
。
我从这里知道正确的实施方式,而不使用used
参数( http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/ ),但我的问题是我的实现有什么问题?
你能阐明一点吗?
为了调试,我每次都打印出“二手”。 打印“ ad”后,已used
参数变为(True,True,True,True),然后没有比这更深的了。 如果我坚持使用used
货,修复used
货的明智方法是什么?
回溯时,您忘记取消设置used[i]
:
def Print_nCk (the_list, k, str_builder, used):
if len(str_builder) == k:
print str_builder
return
else:
for i in xrange(len(the_list)):
if used[i] != True:
str_builder += the_list[i]
used[i] = True
Print_nCk(the_list, k, str_builder, used)
str_builder = str_builder[:-1]
used[i] = False
Print_nCk(['a','b','c','d'], 2, "",[False,False,False,False])
在当前的实现中,从选择 i
作为值的那一刻起,您就将used[i]
设置为True
。 但是,如果稍后您决定选择另一个分支,则应正确进行簿记,从而取消设置used[i]
。
请注意,现在将生成"ab"
和"ba"
。 因此,您将生成具有对称性的组合 。 如果不希望这样,可以使用附加参数 。 这样可以确保您使用的索引不低于先前选择的索引 :
def Print_nCk (the_list, k, str_builder, used, prev = 0):
if len(str_builder) == k:
print str_builder
return
else:
for i in xrange(prev,len(the_list)):
if used[i] != True:
str_builder += the_list[i]
used[i] = True
Print_nCk(the_list, k, str_builder, used, i+1)
str_builder = str_builder[:-1]
used[i] = False
Print_nCk(['a','b','c','d'], 2, "",[False,False,False,False])
然而,这或多或少地破坏了使用“二手”阵列的目的。 您可以简单地使用prev
:
def Print_nCk (the_list, k, str_builder, prev = 0):
if len(str_builder) == k:
print str_builder
return
else:
for i in xrange(prev,len(the_list)):
str_builder += the_list[i]
Print_nCk(the_list, k, str_builder, i+1)
str_builder = str_builder[:-1]
Print_nCk(['a','b','c','d'], 2, "")
然后打印:
>>> Print_nCk(['a','b','c','d'], 2, "")
ab
ac
ad
bc
bd
cd
参加聚会有点晚,但是我认为您应该更多地利用递归。 无需传递任何多余的参数。
这是一个更简单的方法:
def Print_nCk(the_list, size):
combs = []
if size == 1: # the base case
return the_list
for i, c in enumerate(the_list[:-size + 1]):
for sub_comb in Print_nCk(the_list[i + 1:], size - 1): # generate and return all sub-combos of size - 1
combs.append(c + sub_comb) # for each sub-combo, add the sizeth (or n - sizeth) character
return combs
此方法生成size - 1
组合,并将它们与size
th的字符组合在一起。
对于2号组合:
>>> Print_nCk(['a','b','c','d'], 2)
['ab', 'ac', 'ad', 'bc', 'bd', 'cd']
对于3号组合:
>>> Print_nCk(['a','b','c','d'], 3)
['abc', 'abd', 'acd', 'bcd']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.