![](/img/trans.png)
[英]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.