zlatan的算法笔记1.1--回溯中的组合问题(力扣77题)【对于剪枝的理解】

算法笔记1.1

本次内容是对于上次的组合问题进行的优化操作,优化的方法称之为剪枝,字面意思就是省去一些没有必要的操作,从而提高效率。

剪枝

在组合问题当中,我们在取节点的时候我们要注意一个问题,在同一层且取数不重复的情况下,假设我们的n = 4,数组为【1,2,3,4】,如果我们一开始取的数为1,那之后在分支上再取就要在2,3,4当中选,同理我们先取2,在它的分支我们就只能取3,4,这是为了让组合不重复。

回到题目里,当k = 2的时候,不好体现剪枝的作用,所以选取k = 3的情况。从下图可以看出来,有些元素组合的k不满3,很多遍历都是没有意义的,那么优化掉这些不必要的分支是不是就可以提高效率。
请添加图片描述上节谈到树的宽度表示集合的大小,深度表示递归的深度,我们每次剪枝的地方就处于递归过程当中每层for循环的起始位置,那么就可以理解为,如果我们改变for循环中i的条件,是不是就可以就此实现剪枝操作本身。

优化过程

1.找到已经选好的元素个数:原本条件为i <= n,n为元素总个数,已经选好的元素个数就是指在path数组当中被push进去的内容,个数就是path数组的大小,即path.size()。
2.还有没选择过的元素个数:题目要求k个数的组合,没有被选择的元素个数是不是要求个数减去已经选择个数,即k-path.size()。
3.在整个集合当中要在起始位置进行遍历:拿元素总个数n减去未选择过的元素个数即可,n-(k-path.size()),这里就会出现问题,如果就这样设置条件可以发现最后得到的结果会缺少组合,这里是因为没有将初始位置的条件考虑在内,如果不理解可以自行去选择n与k代入式子中就可以理解,所以要在后面+1,就变为了n-(k-path.size())+1

代码部分

for(int i=startIndex; i<=n-(k-path.size())+1; i++){
            path.push_back(i);
            backtracking(n, k, i+1);
            path.pop_back();
        }
    }

总结

剪枝操作比较灵活,面对不一样的题目,考虑的点也会有所不同,但剪枝操作一般会在for循环中i的范围当中去操作,可以让我们更好地提前锁定范围,剩下的部分可能就需要通过题目的积累去慢慢完善本部分的内容,相应的视频讲解为组合剪枝优化,希望大家也能理解题目,有所收获,变得更强!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值