代码随想录训练营-回溯05

用于记录为期60天的算法提升过程,今天是第29天

️代码随想录训练营-回溯️

  • 93. 复原 IP 地址
        • 思路:
        • 代码
  • 46. 全排列
        • 思路:
        • 代码
  • 46. 全排列
        • 思路:
        • 代码

93. 复原 IP 地址

  1. 递增子序列
    给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
    数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

思路:

水平方向不能有重复,竖直方向必须递增。map去除重复,数值上用递归判断即可

代码

var(
    res [][]int
    path []int
)
func findSubsequences(nums []int) [][]int {
    res,path = make([][]int,0),make([]int ,0,len(nums))
    dfs(nums,0)
    return res
}
func dfs(nums[]int ,start int){
    if len(path)>=2{
        tmp:=make([]int,len(path))//
        copy(tmp,path)
        res= append(res,tmp)
    }
    used:=make(map[int]bool,len(nums))
    for i:=start;i<len(nums);i++{
        if used[nums[i]]{ continue}
        if len(path)==0 || nums[i] >=path[len(path)-1]{
            path =append(path,nums[i])
            used[nums[i]] = true
            dfs(nums,i+1)
            path = path[:len(path)-1]
        }
    }
}

46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

思路:

只保留最底层叶子节点,加一个长度判断,加一个hash表判断有没有使用过,不需要重复的数组

代码

var (
    res [][]int 
    path []int 
    hash map[int]bool
)
func permute(nums []int) [][]int {
    res,path = make([][]int,0),make([]int,0,len(nums))
    hash = make(map[int]bool,len(nums))
    dfs(nums,0)
    return res
}
func dfs(nums[]int, cur int){
    if cur == len(nums){
        tmp :=make([]int,len(path))
        copy(tmp,path)
        res = append(res,tmp)
    }
    for i:=0;i<len(nums);i++{
        if hash[nums[i]] ==false{
            path =append(path,nums[i])
            hash[nums[i]] = true
            dfs(nums,cur+1)
            hash[nums[i]] = false
            path = path[:len(path)-1]
        }
    }
}

46. 全排列

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

思路:

这题st换成map为啥行不通???

代码

var (
   res [][]int
   path  []int
   st    []bool   // state的缩写
)
func permuteUnique(nums []int) [][]int {
   res, path = make([][]int, 0), make([]int, 0, len(nums))
   st = make([]bool, len(nums))
   sort.Ints(nums)
   dfs(nums, 0)
   return res
}

func dfs(nums []int, cur int) {
   if cur == len(nums) {
       tmp := make([]int, len(path))
       copy(tmp, path)
       res = append(res, tmp)
   }
   for i := 0; i < len(nums); i++ {
       if i != 0 && nums[i] == nums[i-1] && !st[i-1] {  // 去重,用st来判别是深度还是广度
           continue
       }
       if !st[i] {
           path = append(path, nums[i])
           st[i] = true
           dfs(nums, cur + 1)
           st[i] = false
           path = path[:len(path)-1]
       }
   }
}

你可能感兴趣的:(算法,哈希算法)