leetcode中有兩道經典的題目,求一個數組的排列和組合,都可以用深度優先遞歸搜索的方式來求解,讓我們一起來look look。
排列[ Permutations ]
題:Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路:可以把全排列問題進行分解,變成子問題直至可以直接求解。nums = [1,2,3],可以先固定1,然後將 [2,3] 進行全排的結果加上1即可,之後再固定2,全排[1,3],依次類推…
下面爲對應的代碼,固定某個數,即將它放在start位置,再對start之後的數遞歸全排
要注意的是,在遞歸完成之後,要將原來調換位置的兩個數換回來,使得下一次的調換還是基於原來的順序
因爲它是全排列,所以它的DFS搜索要到n才結束
對於遞歸,要理解的一個關鍵點是,遞歸函數前面的部分是正向運行的,後面的部分是逆向運行的。
class Solution:
def permute(self, nums):
res = []
self.func(nums, 0 ,res)
return res
def func(self,nums, start, res):
if start==len(nums):
res.append(nums.copy())
else:
for i in range(start, len(nums)):
nums[start], nums[i] = nums[i], nums[start]
self.func(nums, start+1, res)
nums[start], nums[i] = nums[i], nums[start]
組合[ Combinations ]
題:Given two integers n and k, return all possible combinations of k numbers out of 1 … n.
Example:
Input: n = 4, k = 2
Output:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
思路:這一題和排列題有相似之處,也有它不一樣的地方,它需要k個元素,而不是所有的n個元素,因此它的DFS搜索到k結束。因此他也需要一個額外的temp數組去保存中間結果。
說實話,對於這裏,start 的含義我也沒有很理解,希望知曉的朋友可以在評論裏說明一下,感謝~
class Solution:
def combine(self, n, k):
if k>n or k<0:
return []
res = []
temp = []
self.func(n, k, 1, temp, res)
return res
def func(self, n, k, start, temp, res):
if len(temp) == k:
res.append(temp.copy())
else:
for i in range(start, n+1):
temp.append(i)
self.func(n, k, i+1, temp, res)
temp.pop()
參考:
https://www.cnblogs.com/grandyang/p/4358848.html
https://www.cnblogs.com/grandyang/p/4332522.html