概述
好吧,我承认文章题目有点标题党了,总的来说就是用lambda表达式让你能够在一个函数之内解决战斗(本人很不喜欢刷题的时候拆开写函数),只要用到递归的地方都能够使用。
函数式编程
什么是函数式编程就不展开说了,这里主要用到Lambda演算理论中的Y Combinator
,通过它我们可以实现匿名的递归调用函数。关于它的解释,一般是所谓的“懂的都懂”,感兴趣的可以去了解一下,这里只讲怎么用。具体来说,就是在c++中,如果你想在lambda表达式中递归调用自己是不行的(当然后面能够做到,不然也就没这篇文章了),编译器会提示你此时还未定义,那么怎么做呢,就是通过Y Combinator
,这也不卖关子了,其实就是把函数自身当成参数传进去即可,这样就可以调用了是不是?
示例
具体怎么写递归不在这篇文章的范围,如果我们想用lambda表达式的话我们应该怎么写?实际上看下面的代码:
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int> > res;
auto func=[&](auto&& func,Node* node,int depth){
if(node==nullptr){
return;
}
if(res.size()==depth){
res.push_back({});
}
res[depth].push_back(node->val);
for(auto child:node->children){
func(func,child,depth+1);
}
};
func(func,root,0);
return res;
}
};
lambda表达的第一个参数不一定要和定义的lambda变量重名,可以叫别的名字(通常起名为self),这样写的目的是方便直观的调用,比如下面这样:
代码如下:
class Solution {
public:
int maxDepth(TreeNode *root) {
int res = 0;
auto dfs = [&](auto self, TreeNode *root) -> int {
if (root == nullptr)
return 0;
int left = self(self, root->left);
int right = self(self, root->right);
return std::max(left, right) + 1;
};
return dfs(dfs, root);
}
};
细心的可能发现了为什么第一种写法的参数需要用&&
而第二个不需要,感兴趣的话可以在下面评论区留言。
结尾
其实一切的起因还是归咎于本人懒,加上代码能力一般实在不想背非递归调用的板子,还是觉得在能保证正确的情况下行数越少逻辑越清晰越好。