一招鲜:排列组合问题的python解法

288 阅读2分钟

我正在参加「掘金·启航计划」

排列组合问题主要有以下几类:

1、笛卡尔积:
itertools.product(set1, set2)

2、排列:
itertools.permutations(list1, num)

3、组合:
itertools.combinations(list1, num)

4、组合(包含自身重复):
itertools.combinations_with_replacement(list1, num)

5、组合(穷举):

for i in range(0, len(list1)):
    items += list(itertools.combinations(list1, i + 1))

**笛卡尔积:

  • 若是单一列表笛卡尔乘积,则包含本身。例子中的aa,bb,cc**
from itertools import product

c = product([1, 2], ['a', 'b', 'c'])
result = []
for i in c:
    result.append(i)
print(result)
# 输出:[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c')]

d = product(['a', 'b', 'c'], ['a', 'b', 'c'])
result = []
for i in d:
    result.append(i)
print(result)

# 输出:[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]

排列:

from itertools import permutations

for i in permutations(['a', 'b', 'c'], 2):
    print(''.join(i), end=" ")
print('\n')
# 输出: ab ac ba bc ca cb


for i in permutations(['a', 'b', 'c'], len(['a', 'b', 'c'])):
    print(''.join(i), end=" ")
print('\n')
# 输出:abc acb bac bca cab cba

组合:

from itertools import combinations

for i in combinations(['a', 'b', 'c'], 1):
    print(''.join(i), end=" ")
# 输出 a b c
print('\n')

for i in combinations(['a', 'b', 'c'], 2):
    print(''.join(i), end=" ")
# 输出 ab ac bc
print('\n')

for i in combinations(['a', 'b', 'c'], 3):
    print(''.join(i), end=" ")
# 输出 abc
print('\n')

组合(包含自身重复):

import itertools

for i in itertools.combinations_with_replacement('ABC', 1):
    print(''.join(i), end=' ')

# 输出 A B C 
print('\n')


for i in itertools.combinations_with_replacement('ABC', 2):
    print(''.join(i), end=' ')

# 输出 AA AB AC BB BC CC
print('\n')


for i in itertools.combinations_with_replacement('ABC', 3):
    print(''.join(i), end=' ')

# 输出 AAA AAB AAC ABB ABC ACC BBB BBC BCC CCC
print('\n')

组合(穷举):

  • 4个元素组合的所有可能
from itertools import combinations

a = [x for x in range(1, 5)]
items = []
for i in range(0, len(a)):
    items += list(combinations(a, i + 1))

print(len(items), items)
# 输出 15 [(1,), (2,), (3,), (4,), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), (1, 2, 3, 4)]

LeetCode 46. 全排列 难度:中等

  • leetcode.cn/problems/pe…
  • 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
class Solution:
    def permute(self, nums):
        result = []
        for i in permutations(nums, len(nums)):
            result.append(list(i))

        return result
  • 运行截图

leetcode1.png

LeetCode 76. 最小覆盖子串 难度:困难

  • leetcode.cn/problems/mi…
  • 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        b_dict = {i: [] for i in t}
        lens = len(s)
        if len(s)<len(t):
            return ""
        for i in range(0, lens):
            if b_dict.get(s[i]) == [] or b_dict.get(s[i]) is not None:
                b_dict[s[i]].append(i)

        c = itertools.product(*list(b_dict.values()))
        d = []
        for i in c:
            i = list(i)
            i.sort()
            d.append(s[i[0]:i[-1] + 1])
        e = d[0]
        for j in d:
            if len(j) < len(e):
                e = j
        return e

  • 运行截图

leetcode2.png