返回

在 LeetCode 中递归实现组合排列算法的两种方法

前端

正文

LeetCode 与组合排列算法

LeetCode 是一家广受欢迎的在线编程评测平台,提供丰富多样的编程题目,供程序员练习和提高技能。组合排列算法是 LeetCode 中常见的算法类型,主要解决从一组元素中选择指定数量元素进行排列或组合的问题。

暴力解法

暴力解法是最简单直接的组合排列算法,其思想是穷举所有可能的情况,然后从中筛选出符合要求的组合或排列。暴力解法的实现相对简单,但时间复杂度较高,尤其是当元素数量较多时。

def combinations(nums, k):
    """
    暴力解法实现组合算法

    :param nums: 输入元素列表
    :param k: 选择元素的数量
    :return: 所有可能的组合
    """
    if k == 0:
        return [[]]

    combinations_list = []
    for i in range(len(nums)):
        sub_combinations = combinations(nums[i+1:], k-1)
        for sub_combination in sub_combinations:
            combinations_list.append([nums[i]] + sub_combination)
    return combinations_list
def permutations(nums, k):
    """
    暴力解法实现排列算法

    :param nums: 输入元素列表
    :param k: 选择元素的数量
    :return: 所有可能的排列
    """
    if k == 0:
        return [[]]

    permutations_list = []
    for i in range(len(nums)):
        sub_permutations = permutations(nums[:i] + nums[i+1:], k-1)
        for sub_permutation in sub_permutations:
            permutations_list.append([nums[i]] + sub_permutation)
    return permutations_list

回溯解法

回溯解法是一种更有效率的组合排列算法,其思想是通过回溯法来搜索所有可能的情况,并在遇到不符合要求的情况时及时回溯。回溯解法的实现略微复杂,但时间复杂度较低,并且可以有效地避免穷举所有的情况。

def combinations_backtrack(nums, k):
    """
    回溯解法实现组合算法

    :param nums: 输入元素列表
    :param k: 选择元素的数量
    :return: 所有可能的组合
    """
    combinations_list = []
    combination = []

    def backtrack(start_index):
        if len(combination) == k:
            combinations_list.append(combination.copy())
            return

        for i in range(start_index, len(nums)):
            combination.append(nums[i])
            backtrack(i + 1)
            combination.pop()

    backtrack(0)
    return combinations_list


def permutations_backtrack(nums, k):
    """
    回溯解法实现排列算法

    :param nums: 输入元素列表
    :param k: 选择元素的数量
    :return: 所有可能的排列
    """
    permutations_list = []
    permutation = []
    visited = set()

    def backtrack(start_index):
        if len(permutation) == k:
            permutations_list.append(permutation.copy())
            return

        for i in range(start_index, len(nums)):
            if i not in visited:
                visited.add(i)
                permutation.append(nums[i])
                backtrack(i + 1)
                permutation.pop()
                visited.remove(i)

    backtrack(0)
    return permutations_list

总结

本文介绍了两种在 LeetCode 中实现组合排列算法的方法,分别是暴力法和回溯法。暴力法简单直接,但时间复杂度较高。回溯法效率更高,并且可以有效地避免穷举所有的情况。在实际应用中,应根据具体情况选择合适的算法。