leetcode_47

淳属虚构 · · 475 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Golang:

写在前面:这题如果是用我46的代码是改不出来的,除非得到所有结果再去删除重复的,但这样自然就没什么意思了,我在这道题上花了差不多整整半天,去研究了深度优先、回溯和剪枝,并试图应用进我的代码里,但最终还是失败了。

思路:可以参见liweiwei大佬的题解,很有帮助。我只在这里描述下我上一题的代码为什么无法应用在这一次的题里。我上一题的解法是,如果有[1,2,3,4,5]这样的数组,我在第一轮的起始数组分别是[1,2,3,4,5],[2,1,3,4,5],[3,2,1,4,5],[4,2,3,1,5]等。即我每次会将第i位和第1位互换,这在全排列里是行得通的。而深度优先加回溯第一轮的起始数组是[1,2,3,4,5],[2,1,3,4,5],[3,1,2,4,5],[4,1,2,3,5]等。注意,在第一轮的数组里,我们去掉第一位数,会变成[2,3,4,5],[1,3,4,5],[2,1,4,5],[2,3,1,5],注意看,它们是不按照顺序排列的,而深度优先的方法处理完的数组则是按顺序排列的。所以,深度优先会保证在变动第i位后,剩下的数组按照顺序排列。而这一题的排列,顺序是很重要的,可以保证我们剪枝的准确性。在初始,我们对nums数组进行排序后,使用深度优先的方法会保证剩下每一次变动都是按照顺序逐步来的,而我原始全排列的方法在第一轮处理后,数组就不按照顺序来了,自然会报错。

代码如下:

func permuteUnique(nums []int) [][]int {
    var res [][]int
    if len(nums)==0 {
        return [][]int{{}}
    }
    sort.Ints(nums)
    used:=make([]int,len(nums))
    var path []int
    dfs(nums,0,&path,used,&res)
    return res
}

func dfs(arr []int,depth int,path *[]int,used []int,res *[][]int)  {
    if depth==len(arr){
        //保存数组并终止递归
        temp:=make([]int,len(arr))
        copy(temp,*path)
        *res= append(*res, temp)
        return
    }
    for i:=0; i<len(arr); i++ {
        if used[i]==0 {
            if i>0&&arr[i]==arr[i-1]&&used[i-1]==0 {
                continue
            }
            *path=append(*path, arr[i])
            used[i]=1
            dfs(arr,depth+1,path,used,res)
            //回溯,起始就是used数组标记回溯+path数组减一(切片实现很麻烦)
            used[i]=0
            temp2:=*path
            temp2=temp2[:len(temp2)-1]
            *path= temp2
        }
    }
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:淳属虚构

查看原文:leetcode_47

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

475 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传