第七章 回溯算法part05(* 491.递增子序列 * 46.全排列 * 47.全排列 II)

学习目标:

  • 491.递增子序列
  • 46.全排列
  • 47.全排列 II

学习内容:* 491.递增子序列

https://programmercarl.com/0491.%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97.html
视频讲解:https://www.bilibili.com/video/BV1EG4y1h78v

本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。
所以不能使用之前的去重逻辑!(使用uset)
不能对原始数组排序,所以要如何去重:uset[nums[i] + 100] = true100的原因是题意里的数范围
只需要记录本层里边重复元素,进入下层递归会重新定义uset,所以uset也不需要做回溯
nums[i] < path[path.length - 1])//注意不要用nums[i] < nums[i-1],for循环时会跳数据,i-1比较是不对的
uset[nums[i]+100]//注意不要写成uset[i+100],去重逻辑
continue//不符合情况下,是接着往后取,而不是循环直接砍掉
var findSubsequences = function(nums) {
    const result = []
    const path = []
    backTracking(0)
    return result
    function backTracking(startIndex){
        if(path.length>1){
            result.push([...path])
        }
        let uset = []
        for(let i=startIndex;i<nums.length;i++){
            if((path.length > 0 && nums[i] < path[path.length - 1]) || uset[nums[i] + 100]) {
                continue//接着往后取,而不是循环直接砍掉
            }
            uset[nums[i] + 100] = true
            path.push(nums[i])
            backTracking(i+1)
            path.pop()
        }
    }
};

学习内容:* 46.全排列

https://programmercarl.com/0046.%E5%85%A8%E6%8E%92%E5%88%97.html
视频讲解:https://www.bilibili.com/video/BV19v4y1S79W

  if(used[i]==1){
     continue // path里已经收录的元素,直接跳过
  }
  //for循环是遍历每层,用过跳过
var permute = function(nums) {
    const result = []
    const path = []
    const used = new Array(nums.length).fill(0)
    backTracking(used)
    return result
    function backTracking(used){
        if(path.length==nums.length){
            result.push([...path])
            return
        }
        for(let i=0;i<nums.length;i++){
            if(used[i]==1){
                continue // path里已经收录的元素,直接跳过
            }
            used[i]=1//同枝
            path.push(nums[i])
            backTracking(used)
            used[i]=0
            path.pop()
        }
    }
};

学习内容:* 47.全排列 II

https://programmercarl.com/0047.%E5%85%A8%E6%8E%92%E5%88%97II.html
视频讲解:https://www.bilibili.com/video/BV1R84y1i7Tm

其实可以对nums先排序,在使用used去重就可以了,没排序用了used和uset去重

使用set去重的版本相对于used数组的版本效率都要低很多
var permuteUnique = function(nums) {
    const result = []
    const path =[]
    const used = new Array(nums.length).fill(0)
    backTracking(used)
    return result
    function backTracking(used){
        if(path.length==nums.length){
            result.push([...path])
            return
        }
        let uset = []
        for(let i=0;i<nums.length;i++){
            if(used[i]==1)continue
            if(uset[nums[i]+10])continue
            used[i]=1
            uset[nums[i]+10]=true
            path.push(nums[i])
            backTracking(used)
            used[i]=0
            path.pop()
        }
    }
};

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值