algorithm - Golang Slice - Java Arraylist - 递归回溯 - 经典算法 Powerset 在 Golang 中无法正常工作
问题描述
我正在尝试使用 Golang 中的递归和回溯来解决 powerset 问题:
给定一组不同的整数 nums,返回所有可能的子集(幂集) 注意:解集不能包含重复的子集。示例:输入:nums = [1,2,3] 输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
这是使用以下 Java 代码通过递归和回溯解决的经典问题:
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}
private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
但是,如果我在 Golang 中执行等效代码,则它不起作用。见下文: // nums :=[]int{1,2,3}
func powerSubSets(nums []int){
result :=[][]int{}
tmp:=[]int{}
powerSubsetsDFS(nums,tmp, 0, result)
fmt.Println("Final Result ",result)
}
func powerSubsetsDFS(nums []int, tmp []int, idx int, result [][]int) {
result = append(result,tmp)
fmt.Println("result idx ",idx,result)
for i:=idx;i<len(nums);i++{
tmp = append(tmp,nums[i])
powerSubsetsDFS(nums,tmp,idx+1,result)
fmt.Println(" subract ", idx , tmp)
tmp = tmp[0:len(tmp)-1]
fmt.Println(" subract after ", idx , tmp)
}
}
如果您看到输出打印:
result idx 0 [[]]
result idx 1 [[] [1]]
result idx 2 [[] [1] [1 2]]
result idx 3 [[] [1] [1 2] [1 2 3]]
subract 2 [1 2 3]
subract after 2 [1 2]
subract 1 [1 2]
subract after 1 [1]
问题是 tmp 切片引用被保持并且当回溯线
tmp = tmp[0:len(tmp)-1]
执行时,它引用了它最近添加到结果中的同一 tmp 切片。理想情况下,不应触摸结果切片。但看起来由于切片引用相同的 tmp 被执行,最终它将把答案留给 []。
我真的在 GoLang 中努力实现这一目标。
解决方案
在这里切片内部
切片是数组段的描述符。它由指向数组的指针、段的长度及其容量(段的最大长度)组成。
您正在追加tmp
然后result
修改,tmp
这意味着tmp
来自循环的最后修改数据将存储在result
.
追加时存储在一个新变量中tmp
并传递它。现在您不需要在追加后删除,因为您使用的是新变量。并i+1
在递归调用时使用。
func powerSubsetsDFS(nums []int, tmp []int, idx int, result [][]int) [][]int {
result = append(result,tmp)
for i:=idx;i<len(nums);i++{
tmp2 := append(tmp, nums[i]) // store in a new variable
result = powerSubsetsDFS(nums,tmp2,i+1,result)
}
return result;
}
func powerSubSets(nums []int){
result :=[][]int{}
tmp:=[]int{}
result = powerSubsetsDFS(nums,tmp, 0, result)
fmt.Println("Final Result ",result)
}
去游乐场的完整代码在这里
推荐阅读
- python - 如何使用 qyery 返回无在 Django 列表视图上获取外键的名称
- python - 正则表达式匹配一个字符串及其周围的 2 个字符
- html - 如何为最近的祖先提供 XPath?
- ios - Ionic IOS 谷歌登录移动“location.protocol”科尔多瓦
- javascript - Formik - 如何清除字段并显示自定义错误
- python - 如何在 python 3.8 中永久保存用户输入的数据?
- python - 如何使用 Telethon,python 仅接收来自电报频道的新消息
- django - pdfkit:包含水印的标题不重复
- c - 为什么 for 循环中的 printf 有人可以解释我吗?
- c# - 以编程方式设置 ListBox 以滚动到所选项目