lc刷题总结(回溯算法第一次)

本文深入探讨了回溯算法在解决经典计算机科学问题中的应用,包括组合问题、全排列问题等,并提供了详细的代码实现和技巧说明。

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

  • lc77. 组合
回溯模板
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}
  • lc216. 组合总和3:有个条件写错了,找了半天,草
  • lc17. 电话号码的字母组合:每次回溯的集合不一样
  • lc39. 组合总和:(可以重复,索引可以选当前的)
  • lc40. 组合总和2:unordered_set<vector< int >>不行,没有针对vector的hash
检验了对深度递归和宽度遍历的理解,感觉挺好
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    void backtrack(int target,int add,vector<int>& candidates,int index)
    {
        if(add==target)
        {
            ans.push_back(temp);
            return;
        }
        for(int i=index;i<candidates.size()&&add+candidates[i]<=target;i++)
        {
            if(i>index&&candidates[i]==candidates[i-1])
            {
                continue;
            }
            temp.push_back(candidates[i]);
            add+=candidates[i];
            backtrack(target,add,candidates,i+1);
            temp.pop_back();
            add-=candidates[i];
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        backtrack( target, 0, candidates, 0);
        return ans;
    }
};
  • lc131. 分割回文串
  • lc93. 复原IP地址
class Solution {
public:
    vector<string> ans;
    void backtrack(string &s,int index,int pointnum)
    {
        if(pointnum==3)
        {
            if(isyes(s,index,s.size()-1))
            {
                ans.push_back(s);
            }
            return;
        }
        for(int i=index;i<s.size();i++)
        {
            if(isyes(s,index,i))
            {
                s.insert(s.begin()+i+1,'.');
                pointnum++;
                backtrack(s, i+2,pointnum);
                s.erase(s.begin()+i+1);
                pointnum--;
            }
            else{
                break;
            }
        }
    }
    bool isyes(string s,int begin,int end)
    {
        if(begin>end) return false;
        else if(s[begin]=='0'&&begin!=end) return false;
        int num=0;
        for(int i=begin;i<=end;i++)
        {
            if(s[i]>'9'||s[i]<'0') return false;
            num=num*10+(s[i]-'0');
        }
        if(num>255) return false;
        return true;
    }
    vector<string> restoreIpAddresses(string s) {
        if(s.size()<4||s.size()>12) return ans;
        backtrack(s, 0, 0);
        return ans;
    }
};
  • lc78. 子集
  • lc90. 子集2
  • lc491. 递增子序列:全是陷阱,题意就弄错了,4767里467竟然也算…(还以为必须要连续的)
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    void backtrack(int index,vector<int>& nums)
    {
        if(temp.size()>=2)
        {
            ans.push_back(temp);
        }
        int uset[201]={0};
        for(int i=index;i<nums.size();i++)
        {  
            if((!temp.empty()&&nums[i]<temp.back())||uset[nums[i]+100]==1)
            {
                continue;
            }
            uset[nums[i]+100]=1;
            temp.push_back(nums[i]);
            backtrack(i+1, nums);
            temp.pop_back();
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        backtrack(0,nums);
        return ans;
    }
};
  • lc46. 全排列:用used数组检测用没用过
  • lc47. 全排列2:利用排序,同时要注意是同一树层还是同一树枝,据此进行去重判断
class Solution {
public:
    vector<vector<int>>ans;
    vector<int> temp;
    int pre;
    void backtrack(vector<int>&nums,vector<bool>&judge)
    {
        if(temp.size()==nums.size())
        {
            ans.push_back(temp);
            return;
        }
        for(int i=0;i<nums.size();i++)
        {
            if(i>0&&nums[i]==nums[i-1]&&judge[i-1]==false)
            {
                continue;
            }
            if(judge[i]==false)
            {
                judge[i]=true;
                temp.push_back(nums[i]);
                backtrack(nums,judge);
                temp.pop_back();
                judge[i]=false;
            }
            
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<bool>judge(nums.size(),false);
        sort(nums.begin(),nums.end());
        backtrack(nums,judge);
        return ans;
    }
};
  • lc332. 重新安排行程:unordered_map<string,map<string,int>>
  • lc51. N皇后:一行一行的回溯
  • lc37. 解数独:双层递归
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值