#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <unordered_map>
#include <cmath>
using namespace std;


 struct TreeNode {
	int val;
	struct TreeNode *left;	
	struct TreeNode *right;
	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 };

 class IsBalanced_Solution_Node {
 public:
	 IsBalanced_Solution_Node(int min=INT_MAX,int max=INT_MIN,int high = 0,bool is_balance=true)
	 :_min(min),_max(max),_high(high),_is_balance(is_balance)
	 {}
	 int _min;
	 int _max;
	 int _high;
	 bool _is_balance;
 };

 IsBalanced_Solution_Node my_IsBalanced_Solution(TreeNode* root) {
	 //对于nullptr我们要不要呢
	 if (root == nullptr) {
		 return IsBalanced_Solution_Node();
	 }
	 IsBalanced_Solution_Node left = my_IsBalanced_Solution(root->left);
	 IsBalanced_Solution_Node right = my_IsBalanced_Solution(root->right);
	 int min = root->val;
	 int max = root->val;
	 int high = 1;
	 bool is_balance = true;
	 if (left._is_balance == false || right._is_balance == false 
		 || std::abs(left._high - right._high) > 1) {
		 is_balance = false;
	 }
	 if (left._high != 0) {
		 min = left._min < min ? left._min : ( min);
	 }
	 if (right._high != 0) {
		 max = right._max > max ? right._max : (max);
	 }
	 high = std::max(left._high, right._high) + 1;
	 return IsBalanced_Solution_Node(min, max, high, is_balance);
 }
 //	判断是不是平衡二叉树
 bool IsBalanced_Solution(TreeNode* pRoot) {
	 // write code here
	 if (pRoot == nullptr) {
		 return true;
	 }
	 return my_IsBalanced_Solution(pRoot)._is_balance;
 }


 class lowestCommonAncestor_Node {
 public:
	 lowestCommonAncestor_Node(TreeNode*root = nullptr)
		 :node(root){}
	 TreeNode* node;

 };
 TreeNode* sum_node = nullptr;
 lowestCommonAncestor_Node my_lowestCommonAncestor(TreeNode* root, int p, int q) {
	 if (root == nullptr) {
		 return lowestCommonAncestor_Node();
	 }
	 lowestCommonAncestor_Node left = my_lowestCommonAncestor(root->left,p,q);
	 lowestCommonAncestor_Node right = my_lowestCommonAncestor(root->right, p, q);
	 //当前的接点有四种可能，
	 //当前的节点是p
	 //当前的节点是q
	 //当前的节点什么都不是，并且是公共的父节点
	 //当前的节点什么也不是
	 TreeNode* re = nullptr;
	 if (left.node == nullptr && right.node == nullptr) {
		 if (root->val == q || root->val == p) {
			 return lowestCommonAncestor_Node(root);
		 }
	}
	 if (left.node != nullptr && right.node != nullptr) {
		 sum_node = root;
		 return lowestCommonAncestor_Node();
	 }
	 if (left.node != nullptr) {
		 if (root->val == p && left.node->val == q) {
			 sum_node = root;
			 return lowestCommonAncestor_Node();
		 }
		 if (root->val == q && left.node->val == p) {
			 sum_node = root;
			 return lowestCommonAncestor_Node();
		 }
		 re = left.node;
	 }
	 if (right.node != nullptr) {
		 if (root->val == p && right.node->val == q) {
			 sum_node = root;
			 return lowestCommonAncestor_Node();
		 }
		 if (root->val == q && right.node->val == p) {
			 sum_node = root;
			 return lowestCommonAncestor_Node();
		 }
		 re = right.node;
	 }
	 return lowestCommonAncestor_Node(re);
 }
 //二叉搜索树的最近公共祖先
 int aalowestCommonAncestor(TreeNode* root, int p, int q) {
	 // write code here
	 //给定一颗二叉树，和两个节点，返回最近的那个公共的节点
	 //有两种方法可以求出这个答案，一个是直接递归求解出我们所需要的答案，
	 // 另一个就是采用并查集进行求解操作
	 //当我们先采用递归的方式求出公共的节点，再采用并查集的操作解出答案
	 sum_node = nullptr;
	 my_lowestCommonAncestor(root, p, q);
	 return sum_node->val;
 }

 class Union {
 public:
	void put(int father, int child) {
		if (get_father(father) == -1) {
			father_map[father] = father;
		}
		if (get_father(child) == -1) {
			father_map[child] = child;
		}
		father_map[child] = get_father(father);
	}
	int get_father(int child) {
		if (father_map.count(child) == 0) {
			return -1;
		}
		queue<int>qu;
		int father = child;
		qu.push(father);
		while (father != father_map[father]) {
			father = father_map[father];
			qu.push(father);
		}
		while (!qu.empty()) {
			father_map[qu.front()] = father;
			qu.pop();
		}
		return father;
	}
	 unordered_map<int, int>father_map;

};

 int re = -1;
 Union un;
void my_union_lowestCommonAncestor(TreeNode* root, int p, int q) {
	if (re != -1) {
		return;
	}
	if (root != nullptr) {
		//每次只有在递归完左树之后，就进行右树的操作，
		//右树递归完之后就将左右树和当前节点合并
		my_union_lowestCommonAncestor(root->left, q, p);
		if (root->left != nullptr) {
			un.put(root->val, root->left->val);
		}
		if (root->val == q && un.get_father(p) != -1) {
			re = un.get_father(p);
		}
		if(root->val == p && un.get_father(q) != -1) {
			re = un.get_father(q);
		}

		 
		my_union_lowestCommonAncestor(root->right, q, p);
		if (root->right != nullptr) {
			un.put(root->val, root->right->val);
		}
		if (root->val == q && un.get_father(p) != -1) {
			re = un.get_father(p);
		}
		if(root->val == p && un.get_father(q) != -1) {
			re = un.get_father(q);
		}
	
	}
}
 //采用并查集的方式进行操作
 //二叉搜索树的最近公共祖先
 int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
	 // write code here
	 my_union_lowestCommonAncestor(root, o1, o2);
	 return re;
 }

 void my_Serialize(TreeNode* root, string& str) {
	 if (root == nullptr) {
		 str.append("#");
	 }
	 else {
		 str.append('{'+ to_string(root->val) + '}');
		 my_Serialize(root->left, str);
		 my_Serialize(root->right, str);
	 }
  }
 //序列化二叉树
 char* Serialize(TreeNode* root) {
	 string str;
	  my_Serialize(root, str);
	 
	 return const_cast<char*>(str.c_str());
 }

 TreeNode* my_Deserialize(  string& str, int& index) {
	 if (str[index] == '#') {
		 index++;
		 return nullptr;
	 }
	 index = str.find('{', index);
	 index = index + 1;
	 int next_index = str.find('}', index);

	 TreeNode* cur = new TreeNode(atoi(str.substr(index, next_index).c_str()));
	 index = next_index + 1;
	 cur->left = my_Deserialize(str, index);
	 cur->right = my_Deserialize(str, index);
 }

 //反序列化二叉树
 TreeNode* Deserialize(char* str) {
	 int index = 0;
	 string ss(str);
	 return my_Deserialize( ss,index);
 }

int main() {
	TreeNode* root = new TreeNode(1);
	root->left = new TreeNode(2);
	root->right = new TreeNode(3);
	 
	return 0;
}