全排列习题分析

习题:(leetcode46)

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

分析:

对于排列问题,就是典型的回溯问题。

使用回溯算法进行求解。

回溯三部曲:

1.回溯函数返回值和参数

2.函数的终止条件

3.函数遍历过程

回溯代码模版:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
    
    for (选择: 本层集合中元素) {
        处理节点;
        backtracking(路径, 选择列表);// 递归
        回溯,撤销处理结果
    }
}

回溯的本质还是暴力求解,通过设置used数组进行标记使用过的数,从头遍历到尾找到满足题目的答案。

代码分析:

class Solution {
private:
    // 存储所有可能的排列组合结果
    vector> result;
    // 存储当前正在构建的排列组合
    vector path;

    // 回溯函数,用于生成排列组合
    void backtracking(vector& nums, vector& used) {
        // 如果path的大小等于nums的大小,说明找到了一个完整的排列
        if (path.size() == nums.size()) {
            // 将当前排列添加到结果集中
            result.push_back(path);
            return;
        }
        // 遍历所有数字,尝试构建排列
        for (int i = 0; i < nums.size(); ++i) {
            // 如果当前数字已经被使用过,跳过以避免重复
            if (used[i] == true) continue;
            // 标记当前数字为已使用
            used[i] = true;
            // 将当前数字添加到当前排列中
            path.push_back(nums[i]);
            // 递归调用,继续构建下一个数字的排列
            backtracking(nums, used);
            // 回溯:撤销选择,将当前数字标记为未使用
            used[i] = false;
            // 从当前排列中移除最后一个数字,为下一次迭代做准备
            path.pop_back();
        }
    }

public:
    // 生成给定数字数组的所有排列组合
    vector> permute(vector& nums) {
        // 创建一个布尔数组,用于标记数字是否已经被使用
        vector used(nums.size(), false);
        // 从第一个数字开始回溯
        backtracking(nums, used);
        // 返回所有可能的排列组合
        return result;
    }
};

你可能感兴趣的:(算法)