全排列的实现之递归版与迭代版

一、递归版


s = ["1","2","3"]
n = len(s)
def dfs(l):
    if l == n:
        print(*s)
        return
    vis = set()
    for i in range(l,n):
        # 防止重复数字,造成答案重复
        if i == l or s[i] not in vis:
            vis.add(s[i])
            s[l],s[i] = s[i],s[l]
            dfs(l + 1)
            s[l],s[i] = s[i],s[l]
dfs(0)

1

二、迭代版


s = "1231"
s = sorted(s)
n = len(s)
print(*s)
while 1:
    i = n - 2
    # 1、从右往左找到第一个升序元素 s[i]
    while i >= 0 and s[i] >= s[i + 1]:
        i -= 1
    if i == -1:
        break
    # 2、从右往左找到第一个大于s[i]的元素 s[j]
    j = n - 1
    while j >= 0 and s[i] >= s[j]:
        j -= 1
    s[i],s[j] = s[j],s[i]
    # 3、[l,r]区间是降序序列,将其变成升序序列
    l,r = i + 1,n - 1
    while l < r:
        s[l],s[r] = s[r],s[l]
        l += 1
        r -= 1
    print(*s)
1 1 2 3
1 1 3 2
1 2 1 3
1 2 3 1
1 3 1 2
1 3 2 1
2 1 1 3
2 1 3 1
2 3 1 1
3 1 1 2
3 1 2 1
3 2 1 1

三、排列递归实现

s = "1234"

def Combine(s,k):
    result = []
    tmp = []
    n = len(s)
    def dfs(i):
        if len(tmp) == k:
            print(*tmp)
            return
        for j in range(i,n):
            # 选
            tmp.append(s[j])
            dfs(i + 1)
            # 不选
            tmp.pop()
    dfs(0)

Combine(s,2)

如果是求所有子集,可以通过二进制的与集合的对应关系来做!

x = 0b111
s = x
while s:
    t = bin(s)[2:].zfill(3)
    s = (s - 1) & x
    print(t)

'''
111
110
101
100
011
010
001
'''

posted @ 2024-07-30 14:50  gebeng  阅读(30)  评论(0)    收藏  举报