回溯算法--全排列

  • 输入: 1,2,3
  • 输出: \[1,2,3, 1,3,2, 2,1,3, 2,3,1, 3,1,2, 3,2,1 ]

注意

  1. 不是组合问题,{1, 2}, {2, 1}是不一样的,因此不可以使用startIndex
  2. 也无关层之间去重,没有重复的元素。
  3. 需要考虑的是选完一个元素后,往下递归还能继续选择前面的元素。

used: 一个标记数组,记录哪些元素在当前路径中已经被使用了,即可解决问题3

代码

cpp 复制代码
class Solution {
private:
	vector<vector<int>> result; 
	vector<int> path;           
	
	// 核心回溯函数
	// nums: 原始数组
	// used: 一个标记数组,记录哪些元素在当前路径中已经被使用了
	void backtracking(const vector<int>& nums, vector<bool>& used) {
		// 1. 递归终止条件
		// 当 path 的长度等于 nums 的长度时,说明找到了一个完整的全排列
		if(path.size() == nums.size()){
			result.push_back(path); // 将当前路径加入结果集
			return;                 // 结束当前递归分支
		}
		
		// 2. 单层搜索逻辑
		// 遍历 nums 中的每一个元素,尝试将其加入当前路径
		for(int i = 0; i < nums.size(); i++){
			// 如果 nums[i] 已经被使用过(在当前 path 中),则跳过,避免重复
			if(used[i])
				continue;
			
			// 3. 处理节点(做选择)
			used[i] = true;         // 标记当前元素已使用
			path.push_back(nums[i]); // 将当前元素加入路径
			
			// 4. 递归调用
			// 进入下一层决策树,继续填下一个位置的数
			backtracking(nums, used);
			
			// 5. 回溯(撤销选择)
			// 当从递归返回时,说明当前分支已经探索完毕
			// 需要将状态恢复到进入递归之前,以便尝试 for 循环中的下一个数字
			used[i] = false;        // 撤销标记
			path.pop_back();        // 将当前元素移出路径
		}
	}
	
public:
	vector<vector<int>> permute(vector<int>& nums) {
		result.clear();
		path.clear();
		// 初始化 used 数组,大小与 nums 相同,初始全为 false
		vector<bool> used(nums.size(), false);
		
		backtracking(nums, used);
		return result;
	}
};

变形--全排列II

  • 输入:nums = 1,1,2
  • 输出: \[1,1,2, 1,2,1, 2,1,1]
  • nums无序

这个就很简单了,加上层之间的去重就可以了,但是需要注意层去重有两种,有序和无序。

这里的nums无序只能使用unordered_set。单层循环逻辑里面加入去重即可。

cpp 复制代码
unordered_set<int> uset;
		for(int i = 0; i < nums.size(); i++){
			if(used[i] || uset.find(nums[i]) != uset.end())
				continue;
			
			uset.insert(nums[i]);
			used[i] = true;         // 标记当前元素已使用
			path.push_back(nums[i]); // 将当前元素加入路径
			
			backtracking(nums, used);
			
			used[i] = false;        // 撤销标记
			path.pop_back();        // 将当前元素移出路径
		}
相关推荐
郝学胜-神的一滴1 天前
AI 编程智能体 17:四步搞定专属AI智能体
大数据·人工智能·python·神经网络·算法·langchain·强化学习
微尘hjx1 天前
【StrongSort 03】多轨迹算法StrongSort改进点
人工智能·算法·yolo·视觉检测·ultralytics·strongsort·轨迹算法
梦帮科技1 天前
QML-04-QGraph-Diff:量子非欧图扩散生成模型与 SE(3) 等变分子晶格逆向合成完整技术指南(上部分)
人工智能·算法·自动化·量子计算·傅里叶分析
七牛开发者1 天前
TokenGate:端到端可训练的 Token 剪枝机制,让大模型 Prefill 提速 11.3 倍
算法·机器学习·剪枝·长上下文·tokengate
H.莓飛1 天前
【数据结构】排序总结与规模实测
linux·服务器·开发语言·数据结构·visual studio·1024程序员节
FLJwu1 天前
运动相机采购实战|第四篇(终章):一张清单走完选型全流程,把风险拦在源头
c语言·开发语言·数码相机·运动相机·oem 量产
码少女1 天前
数据结构——B+树基础
数据结构·b树
牧瀬クリスだ1 天前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
文丑颜不良啊1 天前
LeetCode1141~1160题目解析
java·leetcode