成都网站优化最低价百度官网app
Leetcode131:分割回文串——回溯算法
给一个字符串aab, 如何分割,使得子串 都是回文串,返回所有的分割方案。 答:1、aa,b。 2、a,a, b.
重点,想想树怎么画的。
发现:所有分割方案都在叶子节点上。
path,收集路径的过程,就是找叶子节点过程。
result,把符合的分割子串方案放到result二维数组中。
回溯三部曲:1、函数的参数返回值。2、边界条件。3、单层搜索逻辑。
需要考虑情况的重点1:如何做这个切割符呢?答案startIndex就是分割的线。
边界条件是什么?
如果切割startindex到最后了,说明分割结束,可以处理叶子节点了。这就是边界。
即if(startindex == s.size) 放进结果。return;
这里为什么把所有叶子节点都放回result了。不应该把符合回文要求的path 放回result吗。答案:把判断是否是回文串的逻辑,放入到第3步里面的for循环了。用一个函数isPalindrome()判断。
//判断回文的函数,实现简单。已经知道了起始startindex,终止位置i,那么两边一起向中间搜索,如果所便利的子串都相等的话,那就是回文串了。
重点2:叶子节点里面的切割,如何用代码表示呢?
答:(startindex,i ] 左开右边。
Void backtracking(s,startindex){//边界//for循环,递归for(i=startindex; i<s.size(); i++){if( isPalindrome(s, startindex, i ) ){若是回文,则区间加入path。path.(子串)}else continue;//continue相当于剪枝了//递归逻辑,切割过的地方不能重复切割,所以要i+1backtracking(s, i+1);//回溯过程,回溯就是沿着另外一条树的树干走,没有回溯的话就会一直沿一条树走到底path.pop_back(i); //把下边为i的元素删除。}return;
}
pop_back(),不需要参数传递,删除容器内的最后一个元素,(其实c++底层不是删除最后一个元素,而是取消了最后一个元素的地址映射,用户看起来打印时候,最后一个元素没了)
下面具体实现的代码,记录了我实现过程,以及犯错误和原因解释 也以注释形式写到代码里了、
class Solution {
public:vector<vector<string>> result;vector<string> path;bool isPalindrome(const string& s, int left, int right){while( left < right ){if( s[left] != s[right] ){return false;}left++;right--;}return true;}//回溯算法,三部曲,1、函数返回值和参数。2、边界条件。3、单层搜索逻辑。void backtracking(const string& s, int startIndex){//边界条件if(startIndex >= s.size()) {result.push_back(path);return;}//单层for搜索,for(int i = startIndex; i < s.size(); i++){//错误记录,不能传入参数path,应该传入s,path传入的一定时回文的,s是用来判断的if( isPalindrome(s, startIndex, i) ){//是回文串,则加入path中,错误1,不能加入i,i是整形,path是string,报错。//所以必须用s.substr(),函数,根据起始startindex,终止index位置,变成string类型path.push_back(s.substr(startIndex, i - startIndex + 1));}else{continue;}//递归backtracking(s, i+1);//回溯,path.pop_back 不需要参数。path.pop_back();}return;}vector<vector<string>> partition(string s) {backtracking(s, 0);return result;}
};
疑问:为什么上述2个函数,要吧string s 设置为const, 为什么要加上&符号,必须要加吗?
使用 const
关键字
原因
- 保证数据的只读性:当参数被声明为
const
时,这表明在函数内部不会对传入的对象进行修改。在isPalindrome
和backtracking
函数里,只是读取字符串s
的内容,不会对其进行修改,所以把参数声明为const
可以保证数据的只读性,防止在函数内部意外修改了字符串的内容。 - 增强代码的可读性和可维护性:
const
关键字能够向其他开发者传达函数的使用意图,即该函数不会对传入的参数进行修改,这有助于提高代码的可读性和可维护性。
不使用 const
的影响
若不使用 const
,虽然代码依然可以正常运行,但可能会在函数内部意外修改字符串的内容,从而引发难以调试的错误。并且,其他开发者在阅读代码时,无法明确该函数是否会修改传入的参数。
- 使用引用(
&
)
原因
- 避免不必要的拷贝:在 C++ 里,当把对象作为参数传递给函数时,默认采用值传递的方式,这意味着会对对象进行一次拷贝。对于
std::string
类型的对象,尤其是当字符串很长时,拷贝操作会消耗大量的时间和内存。使用引用传递(&
)可以避免这种不必要的拷贝,直接传递对象的引用,从而提高代码的性能。 - 提高效率:引用传递只需要传递对象的地址,而不需要复制整个对象,这样可以显著减少内存开销和时间开销。