LeetCode113…太裸了,实在没啥好说的,但是我写的程序有点慢,就先把代码贴在这看看以后能不能优化一下。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void digui(vector<vector<int>> &ans, vector<int> res, TreeNode *t, int pathsum, int sum)
{
res.push_back(t->val);
pathsum += t->val;
if (pathsum == sum && !t->right && !t->left)
{
ans.push_back(res);
res.clear();
}
else if (!t->right && !t->left)
{
res.clear();
}
else
{
if (t->left) digui(ans, res, t->left, pathsum, sum);
if (t->right) digui(ans, res, t->right, pathsum, sum);
}
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans;
if (root == NULL) return ans;
vector<int> res;
digui(ans, res, root, 0, sum);
return ans;
}
};
106是从中序和后序遍历的序列里面推出整棵树。
最近在看卜东波老师的算法课,讲到拿到一个问题的时候,你要先考虑最简单的情况、相似的情况和子问题。
在这道题中套一下这个思考路线就能发现后序遍历的最后一个点是根,在中序遍历中找到这个点,左边是左子树,右边是右子树,递归下去就行。因为子树在中序和后续遍历里面都连在一起,所以用l和r记录他们在哪【这个思想有点点像从线段树借鉴过来的?触类旁通嘛】
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* digui(int l1, int r1, int l2, int r2, TreeNode *root, int size, vector<int> inorder, vector<int> postorder)
{
root->val = postorder[r2];
if (size == 1) return root;
int ro;
for (int i = l1; i <= r1; i++)
{
if (inorder[i] == postorder[r2])
{
ro = i;
break;
}
}
int ls = ro - l1, rs = r1 - ro;
root->left = new TreeNode;
if (ls == 1)
{
root->left->val = inorder[ro - 1];
}
else if (ls == 0)
{
root->left = NULL;
}
else
{
root->left = digui(l1, l1 + ls - 1, l2, l2 + ls - 1, root->left, ls, inorder, postorder);
}
root->right = new TreeNode;
if (rs == 1)
{
root->right->val = inorder[ro + 1];
}
else if (rs == 0)
{
root->right = NULL;
}
else
{
root->right = digui(ro + 1, r1, r2 - rs, r2 - 1, root->right, rs, inorder, postorder);
}
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int size = inorder.size();
TreeNode *root = new TreeNode;
if (size == 0) return NULL;
root = digui(0, size - 1, 0, size - 1, root, size, inorder, postorder);
return root;
}
};
要注意考虑树只有一个节点和只有两个节点的特殊情况。
然鹅还是很慢,不过几乎一遍就写出来了有点开心。
题解里面用map构建了一个中序遍历中(元素,下标)的映射,就可以O(1)的找到根在中序遍历中的位置了,总时间复杂度就是O(n),而我写的是O(n^2)