zoukankan      html  css  js  c++  java
  • 菜鸟系列 Golang 实战 Leetcode —— 回溯算法看这几题就够啦 (46. 全排列、47.全排列 II、78. 子集、90. 子集 II、39.组合总和、40. 组合总和 II)

    有兴趣的关注IT程序员客栈哦

    46.全排列
    给定一个没有重复数字的序列,返回其所有可能的全排列。

    示例:
    
    输入: [1,2,3]
    输出:
    [
      [1,2,3],
      [1,3,2],
      [2,1,3],
      [2,3,1],
      [3,1,2],
      [3,2,1]
    ]
    

    题解:

    采用回溯算法解决。

    func permute(nums []int) [][]int {
        var res [][]int
        if len(nums)==0{
            return res
        }
        var tmp []int
        var visited = make([]bool,len(nums))
        backtracking(nums,&res,tmp,visited)
        return res
    }
    func backtracking(nums[]int, res *[][]int, tmp []int, visited []bool){
        // 成功找到一组
        if len(tmp)==len(nums){
            var c = make([]int, len(tmp))
            copy(c,tmp)
            *res=append(*res,c)
            return
        }
        // 回溯
        for i:=0;i<len(nums);i++{
            if !visited[i]{
                visited[i]=true
                tmp=append(tmp,nums[i])
                backtracking(nums,res,tmp,visited)
                tmp=tmp[:len(tmp)-1]
                visited[i]=false
            }
        }
    }
    

    47.全排列 II
    给定一个可包含重复数字的序列,返回所有不重复的全排列。

    示例:
    
    输入: [1,1,2]
    输出:
    [
      [1,1,2],
      [1,2,1],
      [2,1,1]
    ]
    
    func permuteUnique(nums []int) [][]int {
        var res [][]int
        if len(nums)==0{
            return res
        }
        sort.Ints(nums)
        var tmp []int
        var visited = make([]bool,len(nums))
        backtracking(nums,&res,tmp,visited)
        return res
    }
    
    func backtracking(nums []int, res *[][]int,tmp []int, visited []bool){
        if len(tmp)==len(nums){
            var c = make([]int,len(tmp))
            copy(c,tmp)
            *res=append(*res,c)
            return
        }
        for i:=0;i<len(nums);i++{
            // 回溯算法,但是增加一些条件
            if i>0&&nums[i]==nums[i-1]&&!visited[i-1]{
                continue
            }
            if !visited[i]{
                visited[i]=true
                tmp=append(tmp,nums[i])
                backtracking(nums,res,tmp,visited)
                tmp=tmp[:len(tmp)-1]
                visited[i]=false
            }
        }
    }
    

    78.子集
    给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    说明:解集不能包含重复的子集。

    示例:
    
    输入: nums = [1,2,3]
    输出:
    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    
    func subsets(nums []int) [][]int {
        var res [][]int
        if len(nums)<0{
            return res
        }
        var tmp []int
        backtracking(nums,&res,tmp,0)
        return res
    }
    
    
    func backtracking(nums []int,res *[][]int,tmp []int, index int){
        var c = make([]int,len(tmp))
        copy(c,tmp)
        *res=append(*res,c)
        for i:=index;i<len(nums);i++{
            tmp=append(tmp,nums[i])
            // 此处是i+1 ,刚开始跑的时候我一直也成index+1
            backtracking(nums,res,tmp,i+1)
            tmp=tmp[:len(tmp)-1]
        }
    }
    

    90.子集 II
    给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    说明:解集不能包含重复的子集。

    示例:
    
    输入: [1,2,2]
    输出:
    [
      [2],
      [1],
      [1,2,2],
      [2,2],
      [1,2],
      []
    ]
    
    func subsetsWithDup(nums []int) [][]int {
        var res [][]int
        if len(nums)<0{
            return res
        }
        // 排序
        sort.Ints(nums)
        var tmp []int
        var visited =make([]bool,len(nums))
        backtracking(nums,&res,tmp,0,visited)
        return res
    }
    
    
    func backtracking(nums []int,res *[][]int,tmp []int, index int,visited []bool){
        var c = make([]int,len(tmp))
        copy(c,tmp)
        *res=append(*res,c)
        for i:=index;i<len(nums);i++{
            if i>0&&nums[i-1]==nums[i]&&!visited[i-1]{
                continue
            }
            visited[i]=true
            tmp=append(tmp,nums[i])
            backtracking(nums,res,tmp,i+1,visited)
            tmp=tmp[:len(tmp)-1]
            visited[i]=false
        }
    }
    

    39.组合总和
    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的数字可以无限制重复被选取。

    说明:

    所有数字(包括 target)都是正整数。
    解集不能包含重复的组合。
    示例 1:

    输入: candidates = [2,3,6,7], target = 7,
    所求解集为:
    [
      [7],
      [2,2,3]
    ]
    示例 2:
    
    输入: candidates = [2,3,5], target = 8,
    所求解集为:
    [
      [2,2,2,2],
      [2,3,3],
      [3,5]
    ]
    
    func combinationSum(candidates []int, target int) [][]int {
        var res [][]int
        if len(candidates)==0{
            return res
        }
        var tmp []int
        backtracking(candidates,&res,target,tmp,0)
        return res
    }
    
    func backtracking(candidates []int, res *[][]int, target int, tmp []int,index int){
        if target<0{
            return
        }
        if target==0{
            var c = make([]int,len(tmp))
            copy(c,tmp)
            *res=append(*res,c)
            return
        }
        for i:=index;i<len(candidates);i++{
            tmp=append(tmp,candidates[i])
            // 说来惭愧啊,这个地方是i,而不得index    
            backtracking(candidates,res,target-candidates[i],tmp,i)
            tmp=tmp[:len(tmp)-1]
        }
    }
    

    40.组合总和 II
    给定一个数组 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]
    ]
    示例 2:
    
    输入: candidates = [2,5,2,1,2], target = 5,
    所求解集为:
    [
      [1,2,2],
      [5]
    ]
    
    func combinationSum2(candidates []int, target int) [][]int {
        var res [][]int
        if len(candidates)==0{
            return res
        }
        sort.Ints(candidates)
        var tmp []int
        var visited =make([]bool,len(candidates))
        backtracking(candidates,&res,target,tmp,0,visited)
        return res
    }
    
    func backtracking(candidates []int, res *[][]int, target int, tmp []int,index int,visited []bool){
        if target<0{
            return
        }
        if target==0{
            var c = make([]int,len(tmp))
            copy(c,tmp)
            *res=append(*res,c)
            return
        }
        for i:=index;i<len(candidates);i++{
            if i>0&&candidates[i]==candidates[i-1]&&!visited[i-1]{
                continue
            }
            visited[i]=true
            tmp=append(tmp,candidates[i])
            backtracking(candidates,res,target-candidates[i],tmp,i+1,visited)
            tmp=tmp[:len(tmp)-1]
            visited[i]=false
        }
    }
    
    如果你觉得写的不错,请移步www.itkezhan.top或者关注公众号IT程序员客栈
  • 相关阅读:
    第二十篇 sys模块
    第十九章 Python os模块,pathlib 判断文件是目录还是文件
    第三篇 Postman之 Tests(后置处理器,断言)
    第十八篇 模块与包--time&random模块&模块导入import(os.path.dirname(os.path.abspath(__file__)))
    Sublime text3最全快捷键清单
    第十七篇 Python函数之闭包与装饰器
    第二篇 Postman的高阶使用之配置全局变量及局部变量的调用及设置方法(手动方法)
    第六篇 常用请求协议之post put patch 总结
    第十六篇 Python之迭代器与生成器
    PCL—低层次视觉—关键点检测(Harris)
  • 原文地址:https://www.cnblogs.com/i-dandan/p/12443571.html
Copyright © 2011-2022 走看看