#include <iostream> #include <stack> #include <vector> #include <queue> #include <string> #include <list> #include <unordered_map> #include <unordered_set> using namespace std; class TreeNode{ public: TreeNode(int val):val_(val){} int val_; TreeNode* left = nullptr; TreeNode* right = nullptr; }; void v_print(const vector<int>&vs) { for(const auto v: vs) { cout << v << " "; } cout << endl; } void v_print(const vector<vector<int>>&vss) { for(const std::vector<int>& vs:vss) { for(const auto v:vs) { cout << v << " "; } cout << endl; } } void pre(TreeNode* root) { if(nullptr == root) { return; } cout << root->val_ << endl; pre(root->left); pre(root->right); } void pre(TreeNode* root, vector<int>&res) { stack<TreeNode*>st; if(root != nullptr) { st.push(root); } while(!st.empty()) { root = st.top(); st.pop(); res.push_back(root->val_); if((root->right != nullptr))st.push(root->right); if(root->left != nullptr)st.push(root->left); } return; } void pre2(TreeNode* root, vector<int>&res) { stack<TreeNode*> st; TreeNode* cur = root; while(nullptr != cur || !st.empty()) { if(cur != nullptr) { res.push_back(cur->val_); st.push(cur); cur = cur->left; } else { cur = st.top(); st.pop(); cur = cur->right; } } return; } void inorder(TreeNode* root) { if(root == nullptr)return; inorder(root->left); cout << root->val_ << endl; inorder(root->right); } void inorder(TreeNode* root, vector<int>&res) { stack<TreeNode*>st; while(root != nullptr || !st.empty()) { while(root != nullptr) { st.push(root); root = root->left; } root = st.top(); st.pop(); res.push_back(root->val_); root = root->right; } } void inorder2(TreeNode* root, vector<int>&res) { stack<TreeNode*>st; TreeNode* cur = root; while(cur != nullptr || !st.empty()) { if(cur != nullptr) { st.push(cur); cur = cur->left; } else { cur = st.top(); st.pop(); res.push_back(cur->val_); cur = cur->right; } } return; } void pos(TreeNode* root) { if(nullptr == root) { return ; } if(root->left != nullptr)pos(root->left); if(root->right != nullptr)pos(root->right); cout << root->val_ << endl; } void pos(TreeNode* root, vector<int>&res) { stack<TreeNode*>st; if(root != nullptr)st.push(root); while(!st.empty()) { root = st.top(); st.pop(); res.push_back(root->val_); if(root->left)st.push(root->left); if(root->right)st.push(root->right); } reverse(res.begin(),res.end()); return; } void pos1(TreeNode* root,vector<int>&res) { stack<TreeNode*>st; stack<TreeNode*>st1; TreeNode* cur = root; while(cur != nullptr || !st.empty()) { if(cur) { st.push(cur); st1.push(cur); cur = cur->right; } else { cur = st.top(); st.pop(); cur = cur->left; } } while(!st1.empty()) { res.push_back(st1.top()->val_); st1.pop(); } return ; } void levelOrder(TreeNode* root,vector<vector<int>>& res) { queue<TreeNode*>q; if(root != nullptr)q.push(root); while(!q.empty()) { int size = q.size(); vector<int>tmp; for(int i = 0; i < size; ++i) { auto cur = q.front(); q.pop(); tmp.push_back(cur->val_); if(cur->left)q.push(cur->left); if(cur->right)q.push(cur->right); } res.push_back(tmp); } return ; } void levelOrder(TreeNode* root,vector<vector<int>>&res,int index) { if(root == nullptr)return; if(index == res.size())res.push_back({}); res[index].push_back(root->val_); if(root->left != nullptr)levelOrder(root->left,res,index+1); if(root->right!= nullptr)levelOrder(root->right,res,index+1); return; } void levelOrder1(TreeNode* root,vector<vector<int>>&res) { levelOrder(root,res,0); return ; } void zigzagLevelOrder(TreeNode* root, vector<vector<int>>&res) { queue<TreeNode*>q; if(root)q.push(root); while(!q.empty()) { int size = q.size(); vector<int>tmp; for(int i = 0; i < size; ++i) { auto cur = q.front(); q.pop(); tmp.push_back(cur->val_); if(cur->left) q.push(cur->left); if(cur->right)q.push(cur->right); } res.push_back(tmp); } for(int i = 0; i < res.size(); ++i) { if(i % 2 != 0) { reverse(res[i].begin(),res[i].end()); } } return; } void split(const string &s, const string &sep, list<string> &ret) { unsigned int pos_start =0, pos=0; while(true) { pos = s.find(sep, pos_start); if(-1==pos) break; ret.emplace_back(s.substr(pos_start, pos-pos_start)); pos_start = pos+1; } ret.emplace_back(s.substr(pos_start)); } string serialize(TreeNode* root) { if(root == nullptr) return "#"; return to_string(root->val_) + "," + serialize(root->left) + "," + serialize(root->right); } TreeNode* help( queue<string>& q) { string cur = q.front(); q.pop(); if(cur == "#")return nullptr; TreeNode* n = new TreeNode(stoi(cur)); n->left = help(q); n->right = help(q); return n; } TreeNode* deserialize(string data) { list<string>datas; queue<string>q; split(data,",",datas); for(auto str:datas) { q.push(str); } return help(q); } int index_bst = 0; TreeNode* help(const vector<int>& preorder, int lower,int upper,int N) { if(index_bst == N)return nullptr; int val = preorder[index_bst]; if(val < lower || val > upper)return nullptr; ++index_bst; TreeNode* root = new TreeNode(val); root->left = help(preorder,lower,val,N); root->right = help(preorder,val,upper,N); pre(root); cout << "==="<<endl; return root; } TreeNode* bstFromPreorder(const vector<int>& preorder) { int N = preorder.size(); return help(preorder,INT_MIN,INT_MAX,N); } int preOrderIndex = 0; TreeNode* help(vector<int>&pre,int start,int end,unordered_map<int,int>&map) { if(start > end)return nullptr; TreeNode* root = new TreeNode(pre[preOrderIndex++]); int index = map[root->val_]; root->left = help(pre,start,index-1,map); root->right = help(pre,index+1,end,map); return root; } TreeNode* buildTreeFromPreIn(vector<int>&pre,vector<int>&in) { int N = pre.size(); unordered_map<int,int>map; for(int i = 0; i < N; ++i) { map[in[i]] = i; } return help(pre,0,N-1,map); } TreeNode* help(vector<int>& pos,int inS,int inE,int posS,int posE,unordered_map<int,int>&map) { if(inS > inE)return nullptr; TreeNode* root = new TreeNode(pos[posE]); int inIndex = map[root->val_]; int rightTreeSize = inE - inIndex; root->left = help(pos,inS,inIndex-1,posS,posE - rightTreeSize - 1,map); root->right = help(pos,inIndex + 1, inE,posE-rightTreeSize,posE-1,map); return root; } TreeNode* buildTreeFromInPos(vector<int>&in,vector<int>&pos) { int N = in.size(); unordered_map<int,int>map; for(int i = 0; i < N; ++i) { map[in[i]] = i; } return help(pos,0,N-1,0,N-1,map); } int preSt = 0; TreeNode* build(vector<int>&preV,unordered_map<int,int>&map,int posS,int posE,int N) { if(preSt >= N ||posS > posE)return nullptr; TreeNode* root = new TreeNode(preV[preSt++]); if(preSt == N || posS == posE)return root; int posIndex = map[preV[preSt]]; root->left = build(preV,map,posS,posIndex,N); root->right = build(preV,map,posIndex + 1, posE-1,N); return root; } TreeNode* buildTreeFromPrePos(vector<int>&preV,vector<int>&posV) { int N = preV.size(); unordered_map<int, int> map; for (int i = 0; i < N; ++i) { map[posV[i]] = i; } return build(preV,map,0,N-1,N); } void inorder(TreeNode* root, TreeNode* pre, TreeNode* head) { if(root == nullptr)return; inorder(root->left,pre,head); if(head == nullptr)head = root; if(pre!= nullptr)pre->right = root; root->left = pre; pre = root; inorder(root->right); } TreeNode* TreeToDoubleyList(TreeNode* root) { if(root == nullptr)return nullptr; TreeNode* pre = nullptr,*head = nullptr; inorder(root,pre,head); } int minVal = INT_MAX; int closestVal = 0; int dfs(TreeNode* root, double target) { if(root == nullptr)return -1; if(abs(root->val_ - target) < minVal) { minVal = abs(target-root->val_); closestVal = root->val_; } if(root->val_ > target)dfs(root->left,target); else dfs(root->right,target); } int dfs2(TreeNode* root, double target) { TreeNode* cur = root; while(true) { if(cur == nullptr)return -1; if(abs(root->val_ - target) < minVal) { minVal = abs(target-root->val_); closestVal = root->val_; } if(cur->val_ < target)cur = cur->right; else cur = cur->left; } } int closestValue(TreeNode* root, double target) { //递归 // dfs(root,target); //迭代 dfs2(root,target); return closestVal; } int findMin(TreeNode* root) { while(root->left != nullptr)root = root->left; return root->val_; } TreeNode* deleteNode(TreeNode* root, int key) { if(root == nullptr) return nullptr; if(key < root->val_) root->left = deleteNode(root->left,key); else if(key > root->val_)root->right = deleteNode(root->right,key); else if(root->left == nullptr)return root->right; else if(root->right == nullptr)return root->left; else { root->val_ = findMin(root->right); root->right = deleteNode(root->right,root->val_); } return root; } bool isValidBST(TreeNode* root, int max,int min) { if(root == nullptr)return true; if(max != -1 && root->val_ >= max)return false; if(min != -1 && root->val_ <= min)return false; return isValidBST(root->left,root->val_,min) && isValidBST(root->right,max,root->val_); } int preV = INT_MIN; bool isValidBST(TreeNode* root) { //递归 // if(root == nullptr)return true; // bool left = isValidBST(root->left); // bool right = isValidBST(root->right); // if(!left)return false; // if(root->val_ <= preV)return false; // return isValidBST(root->right); //递归 //非递归 TreeNode* pre = nullptr; stack<TreeNode*>st; while(root!= nullptr||!st.empty()) { while(root != nullptr) { st.push(root); root = root->left; } root = st.top(); st.pop(); if(pre!= nullptr && root->val_ <=pre->val_)return false; pre = root; root=root->right; } return true; // return isValidBST(root, -1, -1); } void recover(TreeNode* node) { TreeNode* first = nullptr, *second = nullptr; TreeNode* prev = new TreeNode(INT_MIN); stack<TreeNode*>st; while(node != nullptr || !st.empty()) { while(node != nullptr) { st.push(node); node = node->left; } node = st.top(); st.pop(); if(node->val_ <= prev->val_) { if(first == nullptr) { first = prev; second = node; } else { second = node; } } prev = node; node = node->right; } int tmp = first->val_; first->val_ = second->val_; second->val_ = tmp; } TreeNode* prevR = new TreeNode(INT_MIN); TreeNode* first = nullptr, *second = nullptr; void inorderR(TreeNode* root) { if(root == nullptr)return; inorderR(root->left); if(prevR->val_ > root->val_) { if(first == nullptr) { first = prevR; second = root; } else { second = root; } } prevR = root; inorderR(root->right); } void recover2(TreeNode* root) { if(root == nullptr)return ; inorderR(root); if(first != nullptr && second != nullptr) { int tmp = first->val_; first->val_ = second->val_; second->val_ = tmp; } return ; } TreeNode* help(vector<int>& nums,int start,int end) { if(start > end) return nullptr; int mid = start + (end - start) / 2; TreeNode* root = new TreeNode(nums[mid]); root->left = help(nums,start,mid - 1); root->right = help(nums,mid + 1,end); return root; } TreeNode* sortedArrayToBST(vector<int>&nums) { return help(nums,0,nums.size() - 1); } void dfs(TreeNode* root,vector<int>&res) { if(root == nullptr)return; dfs(root->left,res); res.push_back(root->val_); dfs(root->right,res); return; } TreeNode* balanceBST(TreeNode* root) { vector<int>res; dfs(root,res); return sortedArrayToBST(res); } int numTrees(int n) { vector<int>G(n+1); G[0] = 1; G[1] = 1; for(int i = 2; i <= n; ++i) { for(int j = 1; j <= i; ++j) { G[i] += G[j-1]*G[i-j]; } } return G[n]; } vector<TreeNode*>help(int st,int ed) { vector<TreeNode*>res; if(st > ed)res.push_back(nullptr); for(int i = st; i <= ed;++i) { vector<TreeNode*> leftList = help(st,i-1); vector<TreeNode*> rightList = help(i+1,ed); for(TreeNode* left : leftList) { for(TreeNode* right:rightList) { TreeNode* root = new TreeNode(i); root->left = left; root->right = right; res.push_back(root); } } } return res; } vector<TreeNode*> generateTrees(int n) { if(n == 0) return {}; return help(1,n); } TreeNode* lowestCommonAncestor(TreeNode* root,TreeNode*p,TreeNode*q) { if(root->val_ >p->val_ && root->val_ >q->val_)return lowestCommonAncestor(root->left,p,q); if(root->val_ <p->val_ && root->val_ < q->val_)return lowestCommonAncestor(root->right,p,q); return root; } TreeNode* lowestCommonAncestor1(TreeNode* root,TreeNode* p,TreeNode* q) { while(true) { if(root->val_ >p->val_ && root->val_>q->val_)root = root->left; else if(root->val_ < p->val_ && root->val_ < q->val_)root = root->right; else return root; } } int cnt = 0; TreeNode* LCA(TreeNode* root, TreeNode* p,TreeNode* q) { if(root == nullptr)return root; TreeNode* left = LCA(root->left,p,q); TreeNode* right = LCA(root->right,p,q); if(root->val_ == p->val_ || root->val_ == q->val_) { ++cnt; return root; } return left == nullptr ? right:right == nullptr ?left:root; } TreeNode* lowestCommonAncestor2(TreeNode* root,TreeNode* p,TreeNode* q) { TreeNode* lca = LCA(root,p,q); return cnt == 2 ? lca: nullptr; } TreeNode* dfs(TreeNode* root, unordered_set<int>&set) { if(root == nullptr)return root; if(set.count(root->val_))return root; TreeNode* left = dfs(root->left,set); TreeNode* right = dfs(root->right,set); if(left != nullptr && right != nullptr)return root; if(left != nullptr)return left; if(right != nullptr)return right; return nullptr; } TreeNode* lowestCommonAncestor(TreeNode* root, vector<TreeNode*>nodes) { unordered_set<int>set; for(TreeNode* node :nodes) { set.insert(node->val_); } return dfs(root,set); } void helper(TreeNode*root,string path,vector<string>&res) { if(root->left == nullptr && root->right == nullptr)res.push_back(path); if(root->left != nullptr)helper(root->left,path+"->"+ to_string(root->left->val_),res); if(root->right!= nullptr)helper(root->right,path+"->"+ to_string(root->right->val_),res); } vector<string>binaryTreePaths(TreeNode* root) { vector<string>res; if(root!= nullptr)helper(root, to_string(root->val_),res); return res; } int res = 0; void dfsG(TreeNode* root,int maxVal) { if(root == nullptr)return; if(root->val_>= maxVal)++res; dfsG(root->left,max(maxVal,root->val_)); dfsG(root->right,max(maxVal,root->val_)); return; } int goodNodes(TreeNode* root) { dfsG(root,INT_MIN); return res; } int maxVal = INT_MIN; int helper(TreeNode* root) { if(root == nullptr)return 0; int left = max(0, helper(root->left)); int right = max(0,helper(root->right)); maxVal = max(maxVal,left + right + root->val_); return max(left,right) + root->val_; } int maxSum(TreeNode* root) { helper(root); return maxVal; } double maxAvg = 0; vector<int> sumTree(TreeNode* root) { if(root == nullptr)return vector<int>(2); vector<int>res(2); auto left = sumTree(root->left); auto right = sumTree(root->right); res[0] = left[0] + right[0]+root->val_; res[1] = left[1] + right[1] + 1; maxAvg = max(maxAvg,double(res[0])/double (res[1])); return res; } double maxAverageSubtree(TreeNode* root) { maxAvg = 0; sumTree(root); return maxAvg; } int maxx = INT_MIN; vector<int>dfs(TreeNode* root) { vector<int>res(2); if(root == nullptr)return vector<int>(2); auto left = dfs(root->left); auto right = dfs(root->right); res[0] = left[1] + 1;//左孩子的rightSum res[1] = right[0] + 1;//右孩子的leftSum maxx = max(maxx,max(res[0],res[1])); return res; } int longestZigZag(TreeNode* root) { dfs(root); return maxx == 0 ? 0 : maxx - 1; } class Pair { public: Pair(TreeNode* node,int depth):node_(node),depth_(depth) { } TreeNode* node_ = nullptr; int depth_ = 0; }; Pair getLca(TreeNode* root, int depth) { if(root == nullptr)return Pair(nullptr,depth); auto left =getLca(root->left,depth + 1); auto right = getLca(root->right,depth + 1); if(left.depth_ == right.depth_) { return Pair(root,left.depth_); } else return left.depth_ > right.depth_ ? left:right; } TreeNode* lcaDeepestLeaves(TreeNode* root) { Pair pair = getLca(root,0); return pair.node_; } int maxVal0 = INT_MIN; vector<int>longestPath(TreeNode* root) { if(root== nullptr)return {0,0}; int inr = 1,dcr = 1; //inr表示child里最长上升子序列包含当前node,dcr为最长下降子序列; if(root->left != nullptr) { auto l = longestPath(root->left); if(root->val_ == root->left->val_+1)dcr = l[1] + 1; else if(root->val_ == root->left->val_-1)inr = l[0] + 1; } if(root->right != nullptr) { auto r = longestPath(root->right); if(root->val_ == root->right->val_ + 1)dcr = max(dcr,r[1] + 1); else if(root->val_ == root->right->val_-1)inr = max(inr,r[0]+1); } maxVal0 = max(maxVal0,dcr+inr-1); return {inr,dcr}; } int longestConsecutive(TreeNode* root) { longestPath(root); return maxVal0; } int main() { TreeNode a(0); TreeNode b(1); TreeNode c(2); TreeNode d(3); TreeNode e(4); TreeNode f(5); TreeNode g(6); b.left = &d; b.right = &e; c.left = &f; c.right = &g; a.left = &b; a.right = &c; TreeNode root = a; #define path #ifdef PRE //二叉树三种遍历方式 递归+非递归 vector<int>res,res1; pre(&root,res); pre2(&root,res1); pre(&root); inorder(&root); inorder(&root,res); inorder2(&root,res1); pos(&root); pos(&root,res); pos1(&root,res1); v_print(res); v_print(res1); #elifdef level vector<vector<int>>res,res1; //二叉树的层序遍历 levelOrder(&root,res); levelOrder1(&root,res1); //之字形打印二叉树 zigzagLevelOrder(&root,res); v_print(res); v_print(res1); #elifdef construct // 二叉树的序列化及反序列化 // string res = serialize(&root); // cout << res << endl; // pre(deserialize(res)); vector<vector<int>>res; // //根据前序遍历构建二叉搜索树 // vector<int>preorder{8,5,1,7,10,12}; // levelOrder(bstFromPreorder(preorder),res); // // //根据前序遍历及中序遍历构建二叉树 // vector<int>preV{3,9,1,2,20,15,7}; // vector<int>inV{1,9,2,3,15,20,7}; // levelOrder(buildTreeFromPreIn(preV,inV),res); // // 根据中序遍历及后序遍历构建二叉树 // vector<int>inV{9,3,15,20,7}; // vector<int>posV{9,15,7,20,3}; // levelOrder(buildTreeFromInPos(inV,posV),res); // 根据中序遍历及后序遍历构建二叉树 vector<int>preV{1,2,4,5,3,6,7}; vector<int>posV{4,5,2,6,7,3,1}; levelOrder(buildTreeFromPrePos(preV,posV),res); v_print(res); #elifdef BST //Leecode270 closest binary search tree value // TreeNode b0(4); // TreeNode b1(2); // TreeNode b2(5); // TreeNode b3(1); // TreeNode b4(3); // b1.left = &b3; // b1.right = &b4; // b0.left = &b1; // b0.right = &b2; // cout << closestValue(&b0,3.714286) <<endl; //LeetCode450 // TreeNode b0(5); // TreeNode b1(3); // TreeNode b2(6); // TreeNode b3(2); // TreeNode b4(4); // TreeNode b5(7); // b1.left = &b3; // b1.right = &b4; // b0.left = &b1; // b0.right = &b2; // b2.right = &b5; // pre(deleteNode(&b0,3)); // //LeetCode98 TreeNode b0(1); TreeNode b1(2); TreeNode b2(3); // b1.left = &b0; // b1.right = &b2; // cout << isValidBST(&b1) << endl; // //LeetCode99 // b0.left = &b2; // b2.right = &b1; //// recover(&b0); // recover2(&b0); // pre(&b0); vector<vector<int>>res; // //LeetCode108 // vector<int>nums{-10,-3,0,5,9}; // levelOrder(sortedArrayToBST(nums),res); //Leetcode1382 // TreeNode c0(1); // TreeNode c1(2); // TreeNode c2(3); // TreeNode c3(4); // c0.right = &c1; // c1.right = &c2; // c2.right = &c3; // levelOrder(balanceBST(&c0),res); v_print(res); //LeetCode96 // cout << numTrees(3) << endl; //LeetCode95 // auto trees = generateTrees(3); // for(auto tree:trees) // { // cout << "==" << endl; // pre(tree); // cout << "==" << endl; // } #elifdef LCA //LeetCode235 TreeNode c0(6); TreeNode c1(2); TreeNode c2(8); TreeNode c3(0); TreeNode c4(4); TreeNode c5(7); TreeNode c6(9); TreeNode c7(3); TreeNode c8(5); TreeNode p(2); TreeNode q(8); c0.left = &c1; c1.left = &c3; c1.right = &c4; c4.left = &c7; c4.right = &c8; c0.right = &c2; c2.left = &c5; c2.right = &c6; vector<vector<int>>res; // levelOrder(&c0,res); // cout << lowestCommonAncestor(&c0,&p,&q)->val_<<endl; // cout << lowestCommonAncestor1(&c0,&p,&q)->val_<<endl; //LeetCode1644 // cout << lowestCommonAncestor2(&c0,&p,&q)->val_ << endl; //LeetCode1676 vector<TreeNode*>nodes{&p,&q}; cout << lowestCommonAncestor(&c0,nodes)->val_<<endl; v_print(res); #elifdef path // TreeNode a0(1); // TreeNode a1(2); // TreeNode a2(3); // TreeNode a3(5); // a0.left = &a1; // a0.right = &a2; // a1.right = &a3; // vector<string> strs = binaryTreePaths(&a0); // for(auto & str : strs) // { // cout << str << endl; // } // LeetCode1448 // TreeNode a0(3); // TreeNode a1(1); // TreeNode a2(3); // TreeNode a3(4); // TreeNode a4(1); // TreeNode a5(5); // a0.left = &a1; // a1.left = &a2; // a0.right = &a3; // a3.left = &a4; // a3.right = &a5; // cout << goodNodes(&a0) <<endl; // LeetCode124 // TreeNode a0(-10); // TreeNode a1(9); // TreeNode a2(20); // TreeNode a3(15); // TreeNode a4(7); // a0.left = &a1; // a0.right = &a2; // a2.left = &a3; // a2.right = &a4; // cout << maxSum(&a0)<<endl; // LeetCode1120 // TreeNode a0(5); // TreeNode a1(6); // TreeNode a2(1); // a0.left = &a1; // a0.right = &a2; // cout << maxAverageSubtree(&a0) <<endl; // LeetCode1372 // TreeNode a0(1); // TreeNode a1(1); // TreeNode a2(1); // TreeNode a3(1); // TreeNode a4(1); // TreeNode a5(1); // TreeNode a6(1); // TreeNode a7(1); // // a0.right = &a1; // a1.left = &a2; // a1.right = &a3; // a3.left = &a4; // a3.right = &a5; // a4.right =&a6; // a6.right = &a7; // cout << longestZigZag(&a0) << endl; // LeetCode1123 // TreeNode a0(3); // TreeNode a1(5); // TreeNode a2(1); // TreeNode a3(6); // TreeNode a4(2); // TreeNode a6(0); // TreeNode a7(8); // TreeNode a9(7); // TreeNode a10(4); // a0.left = &a1; // a0.right = &a2; // a1.left = &a3; // a1.right = &a4; // a4.left = &a9; // a4.right = &a10; // a2.left = &a6; // a2.right = &a7; // vector<vector<int>>res; // levelOrder(lcaDeepestLeaves(&a0),res); // v_print(res); // LeetCode549 TreeNode a0(2); TreeNode a1(1); TreeNode a2(3); a1.left = &a0; a1.right = &a2; cout << longestConsecutive(&a1) << endl; #endif return 0; }