文章目录
problem Ⅰ
236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Example 3:
Input: root = [1,2], p = 1, q = 2
Output: 1
my solution 1 DFS
/**
* 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* ans;
int rec(TreeNode* root, TreeNode* p, TreeNode* q){
if(!root)return 0;
int left = rec(root->left, p, q);
int right = rec(root->right, p, q);
int mid = (root == p || root == q);
if(mid + left + right >=2)
ans = root;
return (mid + left + right > 0);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
rec(root, p, q);
return ans;
}
};
time complexity
:
O
(
n
)
O(n)
O(n)
space complexity
:
O
(
n
)
O(n)
O(n)
my solution 2 use parent pointer
/**
* 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
unordered_map<TreeNode*, TreeNode*> maps;
stack<TreeNode*> stk;
stk.push(root);
maps.insert({root, NULL});
while(maps.find(p)==maps.end() || maps.find(q)==maps.end()){
TreeNode* top = stk.top();
stk.pop();
if(top->right){
stk.push(top->right);
maps.insert({top->right, top});
}
if(top->left){
stk.push(top->left);
maps.insert({top->left, top});
}
}
unordered_set<TreeNode*> sets;
while(p){
sets.insert(p);
p = maps[p];
}
while(q){
if(sets.find(q) != sets.end())
return q;
q = maps[q];
}
return NULL;
}
};
time complexity
:
O
(
n
)
O(n)
O(n)
space complexity
:
O
(
n
)
O(n)
O(n)
this solution reduce the search space, but because it is a Heuristic problem,so it is hard to calculate the complexity
problem Ⅱ
297. Serialize and Deserialize Binary Tree
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
Clarification: The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Example 1:
Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]
Example 2:
Input: root = []
Output: []
solution 1 TLE
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res = "";
stack<TreeNode*> stk;
TreeNode* tmp = root;
stk.push(root);
while(!stk.empty()){
TreeNode* top = stk.top();
res.push_back(top->val);
while(top->left){
stk.push(top->left);
top = top->left;
}
if(top->right)
stk.push(top->right);
}
stk.push(root);
while(!stk.empty()){
TreeNode* top = stk.top();
while(top->left){
stk.push(top->left);
top = top->left;
}
res.push_back(top->val);
if(top->right)
stk.push(top->right);
}
return res;
}
// Decodes your encoded data to tree.
int preorderIndex = 0;
TreeNode* rec(string preorder, string inorder, int low, int high){
if(low > high)return NULL;
TreeNode *root = new TreeNode(preorder[preorderIndex++]);
int InorderPos;
for(int i=low; i<=high; i++){
if(inorder[i] == root->val){
InorderPos = i;
break;
}
}
root->left = rec(preorder, inorder, low, InorderPos-1);
root->right = rec(preorder, inorder, InorderPos+1, high);
return root;
}
TreeNode* deserialize(string data) {
int len = data.size();
string preorder = data.substr(0, len/2);
string inorder = data.substr(len, len/2);
return rec(preorder, inorder, 0, preorder.size()-1);
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
NOTE :
i want to get a string contain both the preorder traversals and inorder traversals, and then deserilize it
but finally i got a TLE…
solution 2
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
string serialize(TreeNode* root) {
if(!root) {
return "NULL,";
}
return to_string(root->val)+","+serialize(root->left)+serialize(root->right);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
queue<string> q;
string s;
for(int i=0;i<data.size();i++)
{
if(data[i]==',')
{
q.push(s);
s="";
continue;
}
s+=data[i];
}
if(s.size()!=0)q.push(s);
return deserialize_helper(q);
}
TreeNode* deserialize_helper(queue<string> &q) {
string s=q.front();
q.pop();
if(s=="NULL")return NULL;
TreeNode* root=new TreeNode(stoi(s));
root->left=deserialize_helper(q);
root->right=deserialize_helper(q);
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));