查看: 1303| 回复: 3
跳转到指定楼层
上一主题 下一主题
收起左侧

[高频题] 组合方面的题目,什么时候才需要for循环?

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
刷题刷到combination类,发现大多标准模板长这个样子,以combination sum 举例:
  1. void dfs(candidates, target, start, cur, ans){
  2.    if (target==0) ans.push_back(cur); return;
  3.    for (i=start ~ candidates.size()){
  4.       if (target-candidates[i]<0) break;
  5.       cur.push_back(candidates[i]);
  6.       dfs (candidates, target - candidates[i], i, cur, ans);
  7.       cur.pop_back();    }
  8. }
复制代码
而我发现有以下两道题目的写法并没有start以及for循环这个结构啊,不像典型的回溯模板:
LC22 Generate Parentheses

  1. void dfs(int left, int right, string& out, vector<string>& res){
  2.   if(left>right) return;
  3.   if(left==0 && right==0) res.push_back(out);
  4.   if(left>0) dfs(left-1, right, out+'(', res);
  5.   if(right>0) dfs(left, right-1, out+')', res);
  6. }
复制代码

以及LC494 Target Sum

  1. void dfs(vector<int>& nums, int d, int S, int& ans){
  2.     if(d==nums.size()){
  3.        if(S==0) ans++;
  4.        return;
  5.     }
  6.     dfs(nums, d+1, S-nums[d], ans);
  7.     dfs(nums, d+1, S+nums[d], ans);
  8. }
复制代码
我不知道应不应该把这几道题归纳在一起,但真的感觉它们很像,可是不知道为何后两道题的做法没有套用经典回溯的模板(i.e.   for(i=start ...)  do something;  DFS();  undo something)
请大侠们指点下,什么情况用经典组合题模板,什么时候不要用? 多谢多谢








上一篇:LC358. Rearrange String k Distance Apart 【JAVA】 最后一个CASE, 不通过。求帮助
下一篇:狗家题为何如此让我高攀不起?
全局:
这是backtracking。for loop 是为了尝试所有的possibility,一般subsets combination 一类的都要用。

在start 这个点,所有的candidate都可能是答案。所以要loop 所有candidate然后一个个的recurse。

leetcode上有个帖子叫backtracking general approach什么什么的你可以搜搜。

评分

参与人数 2大米 +4 收起 理由
ttxs2016 + 1 给你点个赞!
14417335 + 3

查看全部评分

回复

使用道具 举报

推荐
owensy 2021-8-20 04:31:45 | 只看该作者
全局:
楼主您好,这个讲起来可能干文字将不太清楚!

是这样的。所有这种让你返回a list of combination的题目,都可以视作:“阶段性决策问题”

怎么理解?

阶段性:每一次递归操作可视作一个”阶段“,比如说你combination,从n中选k个。那么你这个backtracking算法,就肯定有k个阶段。
决策:每个阶段需要做出一次决策,对于combination来说,就是从n个数字(aka candidate)中选一个。也就是你写的那个循环。

所以你认为的递归套循环的模板是这么来的。

然后您问:啥时候用循环?这就要看你是怎么去model你的阶段,以及怎么去model你的决策的了。

对于这个Generate Parentheses来说,你要生成一个长度为2n的括号合法string,那你就有2n个阶段。划分清楚阶段,您的决策就显而易见了,您的决策就是2选1。所以这道题在做决策的时候不需要用到循环。您不妨再想想,如果这道题要你生成的不止一种括号,而是([{....,那您是不是还得写个循环?

所以说,要不要写循环并不是问题的本质,每个阶段的可选决策,才决定了每个递归要怎么写。

希望能帮到您。

要是有什么不清楚的地方也可以继续讨论(求大米

评分

参与人数 2大米 +2 收起 理由
ttxs2016 + 1 很有用的信息!
开心的猪 + 1 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
 楼主| ttxs2016 2021-8-18 09:45:28 | 只看该作者
全局:
谢谢回复。我理解backtracking基本意思,而且如果题目是很接近combination ,subset和permutation都可以做,而且明白每一句是什么意思。

这里主要想对比以下LC22和LC494,感觉乍看上去也是这类的题目啊,可是做法上又有不同,所以希望大侠指点以下,这个不同的底层逻辑是什么~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表