回溯算法的简单使用
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
https://leetcode-cn.com/problems/subsets/solution/shou-hua-tu-jie-zi-ji-hui-su-fa-xiang-jie-wei-yun-/
我模拟了一下递归的工作
func subsets(nums []int) [][]int {
// 保存最终结果
result := make([][]int, 0)
// 保存中间结果
list := make([]int, 0)
backtrack(nums, 0, list, &result)
return result
}
// nums 给定的集合
// pos 下次添加到集合中的元素位置索引
// list 临时结果集合(每次需要复制保存)
// result 最终结果
func backtrack(nums []int, pos int, list []int, result *[][]int) {
// 把临时结果复制出来保存到最终结果
ans := make([]int, len(list))
copy(ans, list)
*result = append(*result, ans)
// 选择、处理结果、再撤销选择
//遍历一遍所有字母,选择则加入临时数组,再进行下一步子步骤,子步骤执行完回退
//假设nums=[1,2,3,4,5,6]
//第一步:加入1,list=[1]
//第二步:递归调用,result=[[],[1]],循环开始,pos=1,加入2,list=[1,2]
//第三步:递归调用,result=[[],[1],[1,2]],循环开始,pos=2,list=[1,2,3]
//...........................................
//result=[[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6]],循环开始,但此时pos=6,len=6,循环不执行,结束最深层递归,返回上一层pos=5减少最后一个元素,list=[1,2,3,4,5]
//pos=5 i=6 len=6 循环结束返回上一层
//pos=4 i=4 list=[1,2,3,4]
//pos=4 i=5 num[5]=6,list=[1,2,3,4,6],进入子递归。。。。。
//....................
//pos=4 i=6 len=6循环结束返回上一层
//pos=3 i=4 list=[1,2,3,5]
//..... list=[1,2,3,5,6]
//list数组直接添加当前递归结点的下一个数,即为遍历左结点
//回溯到上一个状态(根结点)需要对临时数组长度减1,并且该次递归结束(这里右节点和根节点一样,所以不用遍历)
for i := pos; i < len(nums); i++ {
//一直遍历到最底层左叶结点
list = append(list, nums[i])
//递归调用该程序
backtrack(nums, i+1, list, result)
//返回上一个状态并结束本次递归
list = list[0 : len(list)-1]
}
}

浙公网安备 33010602011771号