回溯算法--全排列

  • 输入: 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();        // 将当前元素移出路径
		}
相关推荐
2601_962218612 小时前
万象生鲜系统业财一体化底层打通技术自动生成经营账单
大数据·数据库·人工智能·python·算法
anew___2 小时前
蜂鸣器播放音乐——让 Arduino 唱出旋律
c++·stm32·单片机·嵌入式硬件·c
吞下星星的少年·-·2 小时前
The 2026 ICPC Asia East Continent Online Contest (II)(构造)
数据结构·算法
派葛穆3 小时前
Lerobot -飞特舵机ST-3215双舵机联动(ESP_NOW)
c语言
零依赖极客3 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm
stolentime4 小时前
洛谷P10515 转圈题解
c++·算法·数学建模·贪心算法
tdtsmt4 小时前
穿戴硬件量产工艺实录:天地通电子智能手表主板 SMT 贴片案
c++
和裕5 小时前
蜂窝板 vs 七层瓦楞重型纸箱:大件工业设备运输性能与成本全对比
大数据·运维·网络·人工智能·算法
衡石科技5 小时前
Data_Agent记忆机制与经验复用衡石分析智能体会话记忆与长期学习技术解析
人工智能·科技·学习·算法·企业级bi
Msshu1236 小时前
2~5串锂电快充优选|XSP36 Type‑C升压/升降压快充管理芯片
数据结构·随机森林·贪心算法·排序算法·线性回归·启发式算法