我的个人微信公众号:Microstrong
微信公众号ID:MicrostrongAI
公众号介绍:Microstrong(小强)同学主要研究机器学习、深度学习、计算机视觉、智能对话系统相关内容,分享在学习过程中的读书笔记!期待您的关注,欢迎一起学习交流进步!
知乎专栏:https://zhuanlan.zhihu.com/Microstrong
Github:https://github.com/Microstrong0305
个人博客:https://blog.csdn.net/program_developer
题目链接:
题目描述:
解题思路:
如何求出几个字符的所有排列,很多人都不能一下子想出解决方案。那我们是不是可以考虑把这个复杂的问题分解成小的问题呢?比如,我们把一个字符串看成由两部分组成:第一部分为它的第一个字符,第二部分是后面的所有字符。 在图1中, 我们用两种不同的背景颜色区分字符串的两部分。
我们求整个字符串的排列,可以看成两步:首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。图1就是分别把第一个字符a和后面的b、c等字符交换的情形。首先固定第一个字符(如图1(a)所示),求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符逐一和它后面的字符交换(如图1(b)所示)...
注:(a)把字符串分为两部分,一部分是字符串的第一个字符, 另一部分是第一个字符以后的所有字符(有阴影背景的区域)。 接下来我们求阴影部分的字符串的排列。( b)拿第一个字符和它后面的字符逐个交换。
分析到这里, 我们就可以看出, 这其实是很典型的递归思路。
已经AC的代码:
(1)第一种递归解法:
class Solution:
#方法一:递归解法
def __init__(self):
self.result = []
def Permutation(self, ss):
# 判断输入
if len(ss) == 0:
return []
self.PermutationCore(ss, 0)
sorted(self.result)
return self.result
def PermutationCore(self, str, begin):
# 递归结束的条件:第一位和最后一位交换完成
if begin == len(str):
self.result.append(str)
return
for i in range(begin, len(str)):
# 如果字符串相同,则不交换
if i != begin and str[i] == str[begin]:
continue
# 位置交换,Python中字符串的值是不可以修改的,
# 可以将字符串转换成列表之后修改值,然后用join组成新字符串。
newStr = list(str)
temp = newStr[begin]
newStr[begin] = newStr[i]
newStr[i] = temp
str = ''.join(newStr)
# 递归调用,前面begin + 1的位置不变,后面的字符串全排列
self.PermutationCore(str, begin + 1)
(2)第二种递归的解法:
class Solution:
# 方法二:递归法的第二种写法
def Permutation2(self, ss):
if len(ss) <= 0:
return []
res = list()
self.perm(ss, res, '')
uniq = list(set(res))
return sorted(uniq)
def perm(self, ss, res, path):
if ss == '':
res.append(path)
else:
for i in range(len(ss)):
self.perm(ss[:i]+ss[i+1:], res, path+ss[i])
(3)第三种递归的解法:
这种解法是在牛客网讨论区看到的,代码看着很简洁,但是理解起来很费劲呀!我是看的迷迷糊糊,还是不太懂,先把代码放这里吧!
class Solution:
# 方法三:递归法的第三种写法
def Permutation3(self, ss):
if len(ss) <= 1:
return ss
res = set()
# 遍历字符串,固定第一个元素,第一个元素可以取a,b,c...,然后递归求解
for i in range(len(ss)):
for j in self.Permutation3(ss[:i] + ss[i + 1:]): # 依次固定了元素,其他的全排列(递归求解)
res.add(ss[i] + j) # 集合添加元素的方法add(),集合添加去重(若存在重复字符,排列后会存在相同,如baa,baa)
return sorted(res) # sorted()能对可迭代对象进行排序,结果返回一个新的list
if __name__ == "__main__":
sol = Solution()
str = 'abc'
print(sol.Permutation3(str))
Reference:
【1】《剑指offer》,何海涛著。
【2】https://cuijiahua.com/blog/2017/12/basis_27.html
【3】https://www.nowcoder.com/questionTerminal/fe6b651b66ae47d7acce78ffdd9a96c7?f=discussion