力扣-46-全排列


回溯法模板题

回溯法

感觉这个方法的题目都比较难,全是中等

回溯算法本质上是对深度优先遍历DFS的优化,当已经到达终点/已经没有可以选择(选择都访问过了)的时候,,就向上回退一步
这里引入了一个概念叫“状态”——每一个节点表示了求解问题的不同阶段,而每一次回溯都需要“重置状态”(这在算法中的体现通常是一个方法)

class Solution {
    // 解题思路:看作是填从左往右n个空格
public:
// 递归函数
// 参数:用于保存结果的二维数组、当前排列数组、从左往右第first个位置、单个结果数组长度(即题目给的可用数字数组的长度)
    void backtrack(vector>& res, vector& output, int first, int len){
        // 当已经填到最后一个位置,则将这个结果数组放入二维数组中
        if (first == len) {
            res.emplace_back(output);
            return;
        }
        for (int i = first; i < len; ++i) {
            // 这个first在for循环中是不会变的,一直都是层数——也可以说是要填的第几个位置
            // 动态维护数组,把选中的换到左边去
            swap(output[i], output[first]);
            // 继续递归填下一个数
            backtrack(res, output, first + 1, len);
            // 撤销操作,因为下面的可能性都跑完了,要恢复output数组以供下一次循环使用
            swap(output[i], output[first]);
        }
    }
    vector> permute(vector& nums) {
        vector > res;
        backtrack(res, nums, 0, (int)nums.size());
        return res;
    }
};

百思不得其解的是这两个相同的交换步骤是什么意思
题解的说法是说把数组分成两个部分,左边是已经填过,右边是待填的数,然后这两步就是维护这个数组的

还有就是这个for循环和递归
递归过程应该是填一个序列的