在编写leetcode-2476题目中,需要将二叉搜索树中序遍历变为升序数组。想到在Rust中声明一个局部函数非常简单,并且可以有效防止局部变量名污染空间。探索了在C++中实现局部函数的方法。
先贴最终代码
class Solution {
public:
vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
vector<vector<int>> res;
vector<int> inOrder = toInOrder(root);
for (int query : queries) {
int pos = lower_bound(inOrder.begin(), inOrder.end(), query) - inOrder.begin();
int lower = -1, upper = -1;
if (pos >= inOrder.size()) {
lower = inOrder.back();
res.push_back({lower, upper});
continue;
}
if (inOrder[pos] == query) {
lower = query;
upper = query;
} else {
lower = pos-1 >= 0 ? inOrder[pos-1] : -1;
upper = inOrder[pos];
}
res.push_back({lower, upper});
}
return res;
}
private:
vector<int> toInOrder(TreeNode* root) {
vector<int> res;
// helper
std::function<void(TreeNode*)> inOrder = [&res, &inOrder](TreeNode* root) {
if (root == nullptr) {
return;
}
inOrder(root->left);
res.push_back(root->val);
inOrder(root->right);
};
inOrder(root);
return res;
}
};
递归局部函数的实现
vector<int> toInOrder(TreeNode* root) {
vector<int> res;
// helper
std::function<void(TreeNode*)> inOrder = [&res, &inOrder](TreeNode* root) {
if (root == nullptr) {
return;
}
inOrder(root->left);
res.push_back(root->val);
inOrder(root->right);
};
inOrder(root);
return res;
}
- 常见的
lambda
函数中,会使用auto
自动推断函数类型,但是当函数需要调用自身时,必须先显式声明其类型。
#include <functional> // 包含 functional 文件
...
// std::function<{Return-Value}(parameters)
// 采用上述格式声明inOrder为接受一个TreeNode*作为参数,返回void函数的函数
std::function<void(TreeNode*> inOrder = ...
按上述修改后的函数为
1 std::function<void(TreeNode*)> inOrder = [&res](TreeNode* root) {
2 if (root == nullptr) {
3 return;
4 }
5 inOrder(root->left);
6 res.push_back(root->val);
7 inOrder(root->right);
8 };
第5行和第7行的inOrder
提示an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list
2. 将inOrder
函数添加到capture list
中,可以运行