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

文章记录了作者在60天算法提升过程中,对复原IP地址(去除重复且递增)和两种全排列问题(不含重复和可含重复)的思路及代码实现,涉及深度优先和广度优先搜索策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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]
       }
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七咔七咔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值