Algorithm Golang Slice-Java Arraylist-递归回溯-经典算法集在Golang中无法按预期工作
我试图在Golang中使用递归和回溯来解决功率集问题: 给定一组不同的整数nums,返回所有可能的子集(幂集) 注意:解决方案集不得包含重复的子集。 例子: 输入:nums=[1,2,3] 输出: 这是一个典型的问题,通过使用下面的Java代码进行递归和回溯来解决:Algorithm Golang Slice-Java Arraylist-递归回溯-经典算法集在Golang中无法按预期工作,algorithm,go,recursion,slice,backtracking,Algorithm,Go,Recursion,Slice,Backtracking,我试图在Golang中使用递归和回溯来解决功率集问题: 给定一组不同的整数nums,返回所有可能的子集(幂集) 注意:解决方案集不得包含重复的子集。 例子: 输入:nums=[1,2,3] 输出: 这是一个典型的问题,通过使用下面的Java代码进行递归和回溯来解决: public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> list = new Array
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}
问题是tmp切片引用被保持,并且当回溯线
tmp = tmp[0:len(tmp)-1]
执行时,它引用最近在结果中添加的相同tmp片。理想情况下,不应触摸结果切片。但看起来,由于切片重新引用相同的tmp,最终将把答案留给[]
我在GoLang真的很难做到这一点。切碎内部构件
切片是数组段的描述符。它由一个指针组成
对于阵列,段的长度及其容量(最大值
段的长度)
您正在result
中添加tmp
,然后修改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)
}
func powerSubsetsDFS(nums[]int、tmp[]int、idx int、result[]int][]int){
结果=追加(结果,tmp)
对于i:=idx;i所以,正如您所提到的,问题在于使用slice的方式。slice的大小为3个字(对于64位机器,1个字=8字节(64位)
第一个单词指向切片的第一个元素,第二个单词存储切片的长度,第三个单词存储切片的容量。您可以阅读有关切片的更多信息(一篇初学者友好的文章)
因此,正如您已经知道的那样,您将引用附加到tmp中的值,而不是temp中值的副本
问题的解决方案很简单,创建一个tmp副本并将该副本添加到结果切片中
tmpcpy := make([]int, len(tmp))
copy(tmpcpy, tmp)
result = append(result,tmpcpy)
因此,如果您更改tmp slice,结果中的值将不会受到影响,谢谢。这也有帮助。我犯了理解slice的基本错误。最终,它是一个参考。另外,如果您查看java代码,该代码也正在创建一个新的列表,添加到result中--list.add(new ArrayList(tempList)请澄清您的accual问题是使用idx+1而不是i+1,然后您不需要复制整个数组,只需追加并存储在新变量中,追加在新变量中不会每次都创建新切片,
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[0:len(tmp)-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)
}
tmpcpy := make([]int, len(tmp))
copy(tmpcpy, tmp)
result = append(result,tmpcpy)