小工具知识网

当前位置: 首页 > 行业知识 > 代码随想录算法训练营day26

行业知识

代码随想录算法训练营day26

2026-10-20 21:26:09 来源:互联网转载

题目:39. 组合总和、40.组合总和II、131.分割回文串

参考��接:代码随想录

39. 组合总和

思路:本题有点像以前做过的k数之和,前者使用的是双指针法,但本题没给定取的数的个数,故只能用回溯法。本题同一个数字可以重复取,但我们还是要设置开始位置,我们采用target递减的方法来判断总和。返回条件为target==0,for循环遍历第一个元素的选择,递归遍历后续元素的选择。当目前后续元素大于所需和的时候直接返回(剪枝),注意首先要对数组排序。时间复杂度O(n*2^n)。

class Solution {public:    vector ans;    vector path;    void backtracking(vector& candidates,int target,int begin){        if(target==0){            ans.push_back(path);            return;        }        for(int i=begin;i            if(target//剩下的所需和小于目前候选的元素,直接返回                return;            }            path.push_back(candidates[i]);            backtracking(candidates,target-candidates[i],i);//下一层递归依旧从i开始,因为可以重复            path.pop_back();        }    }    vector        sort(candidates.begin(),candidates.end());        backtracking(candidates,target,0);        return ans;    }};public:    vector        if(target==0){            ans.push_back(path);            return;        }        for(int i=begin;i            if(target//剪枝                return;            }            path.push_back(candidates[i]);            backtracking(candidates,target-candidates[i],i+1);            path.pop_back();        }    }    vector        sort(candidates.begin(),candidates.end());        backtracking(candidates,target,0);        return ans;    }};public:    vector        if(target==0){            ans.push_back(path);            return;        }        for(int i=begin;i            if(target//剪枝                return;            }            if(i0 && candidates[i]==candidates[i-1] && used[i-1]==0){                continue;//去重过程,树层相邻的相同则直接跳过            }            path.push_back(candidates[i]);            used[i]=1;            backtracking(candidates,target-candidates[i],i+1,used);            path.pop_back();            used[i]=0;        }    }    vector        sort(candidates.begin(),candidates.end());        vectorpublic:    vector        if(target==0){            ans.push_back(path);            return;        }        for(int i=begin;i            if(target//剪枝                return;            }            if(ibegin && candidates[i]==candidates[i-1]){                continue;//去重过程,树层相邻的相同则直接跳过            }            path.push_back(candidates[i]);            backtracking(candidates,target-candidates[i],i+1);            path.pop_back();        }    }    vector        sort(candidates.begin(),candidates.end());        backtracking(candidates,target,0);        return ans;    }};public:    bool isPalindrome(const string s,int begin,int end){//左闭右开,判断begin到end是不是回文串        while(begin            if(s[begin]!=s[end-1]){                return false;            }            begin++;            end--;        }        return true;    }    vector//begin为开始位置,end为切割位置        if(ends.size()){//切割结束,            ans.push_back(path);            return;        }        for(int i=end;i            if(!isPalindrome(s,begin,i)){//第一次切割就不是回文串,直接下一种切割                continue;            }            //第一种切割是回文串            path.push_back(string(s.begin()+begin,s.begin()+i));//加入结果            backtracking(s,i,i+1);            path.pop_back();        }    }    vector        backtracking(s,0,1);        return ans;    }};

上一篇:饥荒steam如何建服务器?

下一篇:138的服务器怎么租?