10.3 回溯--子集
子集、排列、组合都可以看作回溯问题。今天先整理子集的部分。
首先贴上回溯的模板:
摘自:https://leetcode-cn.com/problems/subsets/solution/78-zi-ji-hui-su-sou-suo-fa-jing-dian-ti-mu-xiang-2/
backtracking() { if (终止条件) { 存放结果; } for (选择:选择列表(可以想成树中节点孩子的数量)) { 递归,处理节点; backtracking(); 回溯,撤销处理结果 } }
DFS和回溯算法区别
DFS 是一个劲的往某一个方向搜索,而回溯算法建立在 DFS 基础之上的,但不同的是在搜索过程中,达到结束条件后,恢复状态,回溯上一层,再次搜索。因此回溯算法与 DFS 的区别就是有无状态重置
何时使用回溯算法
当问题需要 "回头",以此来查找出所有的解的时候,使用回溯算法。即满足结束条件或者发现不是正确路径的时候(走不通),要撤销选择,回退到上一个状态,继续尝试,直到找出所有解为止
题目:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
class Solution { public: vector<vector<int>> res; vector<vector<int>> subsets(vector<int>& nums) { // 记录走过的路径 vector<int> track; backtrack(nums, 0, track); return res; } void backtrack(vector<int>& nums, int start, vector<int>& track) { res.push_back(track); for (int i = start; i < nums.size(); i++) { // 做选择 track.push_back(nums[i]); // 回溯 backtrack(nums, i + 1, track); // 撤销选择 track.pop_back(); } } };