回溯算法(排列、组合、子集)

144 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

回溯算法

了解回溯算法链接:https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-xiang-jie-by-labuladong-2/

	//回溯算法,决策树(包含重复数字的话,重复排列也会返回)--全排列
	void BackTrack(vector<int>& nums, vector<int>& back, vector<vector<int>>& res, vector<int>& visited)
	{
		if (nums.size() == back.size())
		{
			res.push_back(back);
			return;
		}

		for (int i = 0; i < nums.size(); i++)
		{
			//把重复的数去掉,不进行处理
			if (visited[i] == 1)
				continue;
			back.push_back(nums[i]);
			visited[i] = 1;
			//进入到下一层决策树
			BackTrack(nums, back, res, visited);
			//回溯
			back.pop_back();
			visited[i] = 0;
		}
	}


	//回溯算法,决策树(包含重复数字的话,重复排列进行过滤后返回)--全排列
	void FilterBackTrack(vector<int>& nums, vector<int>& back, vector<vector<int>>& res, vector<int>& visited)
	{
		if (nums.size() == back.size())
		{
			res.push_back(back);
			return;
		}

		for (int i = 0; i < nums.size(); i++)
		{
			//把重复的数去掉,不进行处理,同时删除重复的排列情况
			if (visited[i] == 1 || (i > 0 && nums[i] == nums[i - 1] && visited[i - 1] == 0))
				continue;
			back.push_back(nums[i]);
			visited[i] = 1;
			//进入到下一层决策树
			FilterBackTrack(nums, back, res, visited);
			//回溯
			visited[i] = 0;
			back.pop_back();
		}
	}

	//组合
	//给定n,k。即在1~n的整数区间之内所有k个数的组合
	void CombineBackTrack(int n, int k, int start, vector<int>& back, vector<vector<int>>& res)
	{
		if (back.size() == k)
		{
			res.push_back(back);
			return;
		}

		for (int i = start; i <= n; i++)
		{
			back.push_back(i);
			CombineBackTrack(n, k, i + 1, back, res);
			back.pop_back();
		}
	}

	//子集
	void SubsetsBackTrack(vector<int>& nums, int start, vector<int>& back, vector<vector<int>>& res)
	{
		res.push_back(back);
		for (int i = start; i < nums.size(); i++)
		{
			back.push_back(nums[i]);
			SubsetsBackTrack(nums, i + 1, back, res);
			back.pop_back();
		}
	}

int main()
{
	vector<int> arr{ 1,2,1 };
	vector<vector<int>> res;
	vector<int> back;
	vector<int> visited(arr.size(), 0);
    //全排列之前需要进行排序
	sort(arr.begin(), arr.end());
	FilterBackTrack(arr, back, res, visited);

	vector<vector<int>> resCombine;
	vector<int> backCombine;
    //组合
	CombineBackTrack(4, 2, 1, backCombine, resCombine);

	vector<int> nums{ 1,2,3 };
	vector<vector<int>> subsetsRes;
	vector<int> backSubsets;
    //子集
	SubsetsBackTrack(nums, 0, backSubsets, subsetsRes);
	return 0;
}

版权声明:本文为CSDN博主「ufgnix0802」的原创文章:
原文链接:(blog.csdn.net/qq135595696…)