回溯算法--全排列

  • 输入: [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();        // 将当前元素移出路径
		}
相关推荐
染指11101 小时前
3.AI大模型-token是什么-大模型底层运行机制
人工智能·算法·机器学习
谙弆悕博士1 小时前
快速学C语言——第19章:C语言常用开发库
c语言·开发语言·算法·业界资讯·常用函数
光影少年1 小时前
前端算法题
前端·javascript·算法
南宫萧幕2 小时前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
电魂泡哥2 小时前
CMS垃圾回收
java·jvm·算法
Teleger2 小时前
在window上使用c++控制鼠标点击,实现的exe
c++·单片机·计算机外设
hkj88082 小时前
CRC-512算法输出64字节
算法
@我漫长的孤独流浪2 小时前
计算机系统核心概念与性能优化全解析
算法·计算机外设
如竟没有火炬2 小时前
接雨水22
数据结构·python·算法·leetcode·散列表