力扣HOT100(35)回溯-全排列

核心思路:回溯法(填空格思想)

我们可以把全排列想象成:有 n 个空格,我们要把数组里的 n 个数,一个一个填进去,每个数只能用一次

回溯法就是模拟这个 "填空" 的过程:

  1. 从第一个空格开始,尝试所有没被用过的数
  2. 选一个数填进去,标记为 "已使用"
  3. 递归填下一个空格
  4. 填完所有空格,得到一个排列,保存结果
  5. 回溯:把刚才填的数拿出来,标记为 "未使用",尝试下一个数

这就是回溯最核心的三步:做选择 → 递归 → 撤销选择

方法一:标记数组版(面试首选,最好写、最好懂)

1. 思路详解

用一个 used 布尔数组,标记哪个数已经被用过了,不能再选。

  • 终止条件:当前排列的长度等于数组长度,说明所有空格都填完了
  • 循环:遍历所有数,没被用过的就可以选
  • 做选择:把数加入当前排列,标记为已用
  • 递归:填下一个位置
  • 撤销选择:把数从当前排列移除,标记为未用
cpp 复制代码
class Solution {
public:
    //写一个回溯函数
    void backtrack(vector<vector<int>>& res,vector<int>& output,int first,int len){


        /*output:当前的数组
first:现在要填第几个位置
len:数组长度(固定不变)
i:用来遍历,把后面的数字一个个换到 first 位置*/

        //填完了
        if(first == len){
            res.emplace_back(output);//把结果存入
            return;
        }


        for(int i  = first;i< len;i++){
            //动态维护数组
            swap(output[i],output[first]);
            //继续递归填下一个数
            backtrack(res,output,first+1,len);
            //撤销操作
             swap(output[i],output[first]);
        }
    }


    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;

        backtrack(res,nums,0,(int)nums.size());

        return res;
        
    }
};
相关推荐
MrZhao40010 小时前
一个最小 Agent 是怎么跑起来的:Agent Loop 与工具使用全链路
算法
Keven_1110 小时前
算法札记:二分
算法·二分
TCW112111 小时前
AI底层系列:用C++实现线性代数的公式推导与算法设计-6.线性方程组的解集
c++·人工智能·算法
luoyayun36111 小时前
从零实现 EBU R128 LUFS 响度分析:K-weighting 滤波、双门限算法
算法·lufs响度分析
小糯米60111 小时前
JS 数组
数据结构·算法·排序算法
拳里剑气11 小时前
C++算法:链表
c++·算法·链表
凌波粒11 小时前
LeetCode--90.子集II(回溯算法)
数据结构·算法·leetcode
旧曲重听111 小时前
2026前端技术从「夯」到「拉」
前端·程序人生·职场和发展·软件工程
旖-旎11 小时前
《LeetCode 417 太平洋大西洋水流问题 FloodFill DFS 解法》
c++·算法·深度优先·力扣·floodfill
凌波粒11 小时前
LeetCode--46.全排列(回溯算法)
数据结构·算法·leetcode