You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言传递切片指针生成全排列时出现异常结果求助

解决Go语言全排列生成中的重复结果问题

我一眼就看出问题所在了——你的代码踩了Go语言切片引用特性的坑!导致最终输出的全排列出现大量重复,下面来一步步分析和修复:

问题根源

  1. 切片引用共享底层数组:当你执行*res = append(*res, s)时,并没有真正把当前排列的副本存入结果集,而是把切片s的引用加了进去。后续递归回溯时对s的修改(比如s = s[:len(s)-1])会直接修改已经存在于res中的切片内容,因为它们共享同一个底层数组。
  2. 递归中的切片复用覆盖:整个递归过程中你一直在复用同一个切片s,回溯操作会不断修改它的长度和内容,最终导致之前保存的排列被覆盖,出现重复的结果。

修复后的代码

只需要在保存结果的时候,创建一个当前切片s的副本存入结果集即可,修改后的完整代码如下:

package main

import "fmt"

func permute(nums []int) [][]int {
	var res [][]int
	var s []int
	permuteHlp(&res, nums, 0, s)
	return res
}

func permuteHlp(res *[][]int, nums []int, i int, s []int) {
	if i == len(nums) {
		// 创建当前切片的副本,避免后续修改影响已保存的结果
		temp := make([]int, len(s))
		copy(temp, s)
		*res = append(*res, temp)
		return
	}
	for j := i; j < len(nums); j++ {
		s = append(s, nums[j])
		nums[i], nums[j] = nums[j], nums[i]
		permuteHlp(res, nums, i+1, s)
		s = s[:len(s)-1]
		nums[i], nums[j] = nums[j], nums[i]
	}
}

func main() {
	x := []int{1,2,3,4}
	y := permute(x)
	fmt.Println(y)
}

为什么这样修复?

当我们执行copy(temp, s)时,会把s中的元素逐一复制到新创建的切片temp中,这个temp拥有独立的底层数组,后续对s的任何修改都不会影响它。这样每一个排列都会以独立的切片形式存入结果集,就不会出现重复的情况了。

另外,你也可以用更简洁的写法替代make+copy:

*res = append(*res, append([]int(nil), s...))

这种方式通过append一个空切片并展开s的元素,同样能创建出独立的切片副本。

运行修复后的代码,就能得到[1,2,3,4]的所有24个不重复的全排列了。

内容的提问来源于stack exchange,提问作者user9823642

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:33