[leetcode]回溯总结

回溯的关键点:递归函数的参数设计,递归之前push_back,递归之后pop_back。

1) Word Break II

首先使用动态规划计算出子串s[i]...s[j]是否能够被分割成多个单词。(见Work Break)

然后递归的创建句子。递归函数的参数有当前处理的s的开头下标begin,当前已经选择了的单词的集合temp,最终结果的集合result。

当begin到达s的末尾时,说明已经找到了一种合理的分割方式,那么将当前已经选择了的全部单词(在temp中)组成句子,将句子加入到result中。

当begin还没到达s的末尾时,枚举从begin开始,下一次分割的位置k,如果这个分割使得从s[i]到s[k]构成一个单词,同时从s[k+1]往后的部分也能被成功分割。那么,这就是一种可能的选择,将这个单词加入到temp,递归的进入分割从s[k+1]到s末尾的工作。当递归结束之后,应该讲当前这个单词从temp中删除,回溯的寻找其他的结果。

2) Palindrome Partition

首先使用动态规划计算出子串s[i]...s[j]是否是回文。

然后递归的创建分割。递归函数的参数有当前处理的s的开头下标begin,当前已经分割得到的回文集合temp,最终结果的集合result。

当begin到达s的末尾时,说明已经找到了一种合理的分割方式,那么将当前已经得到的全部回文单词集合temp加入到result中。

当begin还没到达s的末尾时,枚举从begin开始,下一次分割的位置k,如果这个分割使得从s[i]到s[k]构成一个回文,则递归的进入分割s[k+1]到s末尾的工作。

3) Restore IP Addresses

递归函数参数包括当前处理的string下标begin,当前这次递归得到的IP分割中间结果temp,已经得到的有效IP的结果集合result。

如果当前处理的下标begin已经等于s.length(),判断当前得到的中间结果temp是否是分割成四段。如果不是,直接返回,说明不是有效的IP分割。如果是,则判断每一段是否有前导0,如果没有则是有效IP分割,放到result中。

如果begin没到达s.length()。枚举下次分割的位置,计算以此位置分割得到的数值,如果数值超过255则返回,否则将这次的分割记录到temp中,递归的分割下一部分。回溯是指,当递归结束后,将当前的分割从temp中删除,尝试将分割的位置后移一位。

4) Subsets I II

递归函数参数包括当前处理的数组下标begin,当前得到的子集temp,当前得到的子集集合result。

如果begin等于n,则当前得到一个新的子集,加入到result中。

如果begin不等于n,则枚举下一个要加入子集的元素下标,将该元素加入temp,递归的处理后面的数组。回溯时将该元素从temp中删除,继续枚举下一个元素。

注意,当枚举的元素下标到达n时,应当额外的写一条语句,将当前的temp加入到result中。

    void build(vector<int> &S, int begin, vector<int> temp, vector<vector<int>> &result)
    {
        int n = S.size();
        if(begin == n)
        {
            result.push_back(temp);
            return;
        }
        
        int i;
        for(i=begin;i<n;i++)
        {
            temp.push_back(S[i]);// pick S[i]
            build(S, i+1, temp, result);// solve sub-problem recursively
            temp.pop_back();// delete S[i]
        }
        // when i=n-1 and S[n-1] is pop_back, i++, the cycle is stoped
        // then, the corresponding subset is not pushed into result
        // so push it
        result.push_back(temp);


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值