解题思路
递归思想: n个字符的排列可以转化为 先从n个字符当中pick出一个,然后再对剩余n-1个全排列。
例如: abcd, f(‘abcd’) = [‘a’ + f(‘bcd’)] + [‘b’ + f(‘acd’)] + [‘c’ + f(‘abd’)] + [‘d’ + f(‘abc’)]
找到这种前后递归关系后, 就可以轻松写下如下代码。但需要注意的是, 可能会有如下重复的情况出现, 因此, 用set来添加新排列。
class Solution:
def Permutation(self , str: str) -> List[str]:
if not str: return []
if len(str) == 1: return str
res = set()
for i, char in enumerate(str):
prms = self.Permutation(str[:i]+str[i+1:])
for prm in prms:
res.add(char+prm)
return list(res)
题目变换:求字符的所有组合(必须按先后顺序)
如"abc"的所有组合是[“a”,“b”,“c”,“ab”,“bc”,“ac”,“abc”]
递归思想: n个字符的组合可以转化为 先从n个字符当中pick出一个, 然后求剩余n-1个字符的所有组合
class Solution:
def Permutation(self , str: str) -> List[str]:
def permutation(str):
if not str: return []
if len(str) == 1: return ['',str]
res = set()
char = str[0]
prms = permutation(str[1:])
for prm in prms:
res.add(char+prm)
res.add(prm)
return list(res)
res = permutation(str)
res.remove("")
return res
题目变换:求字符的所有组合(可以调换先后顺序)
如"abc"的所有可能组合为[“ab”,“ac”,“bc”,“abc”,“c”,“bca”,“cab”,“acb”,“b”,“cb”,“a”,“bac”,“ca”,“ba”,“cba”]
递归思想: n个字符的组合可以转化为 第一个字符可选可不选, 求剩余n-1个字符的所有组合
class Solution:
def Permutation(self , str: str) -> List[str]:
def permutation(str):
if not str: return []
if len(str) == 1: return ['',str]
res = set()
for i, char in enumerate(str):
prms = permutation(str[:i]+str[i+1:])
for prm in prms:
res.add(char+prm)
res.add(prm)
return list(res)
res = permutation(str)
res.remove("")
return res
总结
递归很重要的一点是将原问题合理地划分为子问题, 找到原问题与子问题的关系, 即为递归转移条件。