递归与回溯基础![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8168e47b169134323c47f469d8c15524.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/744ca4aa717fab09d738bceb6bcb51ad.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200506233659172.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzAyMTMzNw==,size_16,color_FFFFFF,t_70
leetcode_78_subsets 求子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
golang实现
func subsets1(nums []int) [][]int {
i := 0
item := []int{}
result := [][]int{}
result = append(result, item)
generate(i, nums, &item, &result)
return result
}
func generate(i int, nums []int, item *[]int, results *[][]int) {
if i >= len(nums) {
return
}
*item = append(*item, nums[i])
temp := make([]int, len(*item))
for i, v := range *item {
temp[i] = v
}
*results = append(*results, temp)
generate(i+1, nums, item, results)
*item = (*item)[:len(*item)-1] //回溯
generate(i+1, nums, item, results)
}
golang的位运算法实现
func subsets(nums []int) [][]int {
allSets := 1 << uint(len(nums)) //比如3个元素的子集有2的3次方个
var result [][]int
for i := 0; i < allSets; i++ {
var item []int
temp := i
for j := 0; j < len(nums); j++ {
if temp&1 == 1 {
item = append(item, nums[j])
}
temp >>= 1
}
result = append(result, item)
}
return result
}
leetcode_90:求子集二
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
golang实现
func subsetsWithDup(nums []int) [][]int {
setMap := make(map[string]bool, 0)
i := 0
item := []int{}
result := [][]int{}
result = append(result, item)
sort.Ints(nums)
generate1(i, nums, &item, &result, setMap)
return result
}
func generate1(i int, nums []int, item *[]int, results *[][]int, setMap map[string]bool) {
if i >= len(nums) {
return
}
*item = append(*item, nums[i])
temp := make([]int, len(*item))
for i, v := range *item {
temp[i] = v
}
tempByte, _ := json.Marshal(temp)
if ok := setMap[string(tempByte)]; !ok {
*results = append(*results, temp)
setMap[string(tempByte)] = true
}
generate1(i+1, nums, item, results, setMap)
*item = (*item)[:len(*item)-1] //回溯
generate1(i+1, nums, item, results, setMap)
}
leetcode_40_combinationSum
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
golang实现
func combinationSum2(candidates []int, target int) [][]int {
setMap := make(map[string]bool, 0)
item := []int{}
result := [][]int{}
sort.Ints(candidates)
generate2(0, candidates, &item, &result, setMap, target, 0)
return result
}
func generate2(i int, nums []int, item *[]int, results *[][]int, setMap map[string]bool, target int, sum int) {
if i >= len(nums) || sum > target {
return
}
*item = append(*item, nums[i])
temp := make([]int, len(*item))
sum += nums[i]
for i, v := range *item {
temp[i] = v
}
tempByte, _ := json.Marshal(temp)
ok := setMap[string(tempByte)]
if !ok && sum == target {
*results = append(*results, temp)
setMap[string(tempByte)] = true
}
generate2(i+1, nums, item, results, setMap, target, sum)
sum -= nums[i]
*item = (*item)[:len(*item)-1] //回溯
generate2(i+1, nums, item, results, setMap, target, sum)
}