回溯算法--全排列

  • 输入: 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();        // 将当前元素移出路径
		}
相关推荐
典典分享指南8 分钟前
VS Code Git 工作树:解锁多分支并行开发新体验
算法·决策树·逻辑回归·启发式算法
_Narcissus_39 分钟前
枚举和模拟算法笔记
c语言·数据结构·c++·笔记·算法·模拟·枚举
天疆说1 小时前
策略的进化:从随心所欲到稳健前行
算法
冻柠檬飞冰走茶1 小时前
《数据结构实验指导-C++语言版》 在顺序表 list 中查找元素 x
开发语言·数据结构·c++·算法·list
Brilliantwxx1 小时前
【C++】 高阶数据结构图(1)并查集
开发语言·数据结构·c++
小鱼仙官1 小时前
Ubuntu C++ NTP校时程序
linux·c++·ubuntu
happyprince2 小时前
03-深刻观-CodeX哲学与升华(源码)
算法·ai编程
不会打球的王子2 小时前
Day 27:迁移学习与微调 — 站在巨人的肩膀上
算法
老当益壮梁奶奶2 小时前
Linux软件编程学习笔记(二)Linux文件IO编程入门:从fopen到fgetc
linux·c语言·c++·笔记·学习
sunoo-2292 小时前
C 语言文件 IO 全攻略:从基础函数到实战踩坑(BMP 读取 + 词典查询)
linux·c语言·前端·笔记·vscode·学习