二叉树
二叉树遍历
二叉树前序遍历
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : vector<int > ans; vector<int > preorderTraversal (TreeNode* root) { dfs (root); return ans; } void dfs (TreeNode* root) { if (!root) return ; ans.push_back (root->val); dfs (root->left); dfs (root->right); } };
用栈模拟递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : vector<int > preorderTraversal (TreeNode* root) { vector<int > ans; if (!root) return ans; stack<TreeNode*> stk; stk.push (root); while (stk.size ()) { auto now = stk.top (); stk.pop (); ans.push_back (now->val); if (now->right) stk.push (now->right); if (now->left) stk.push (now->left); } return ans; } };
沿左分支自顶向下遍历沿途节点,再自顶向上遍历右子树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution {public : vector<int > preorderTraversal (TreeNode* root) { vector<int > ans; if (!root) return ans; stack<TreeNode*> stk; while (root || stk.size ()) { while (root) { ans.push_back (root->val); stk.push (root); root = root->left; } root = stk.top ()->right; stk.pop (); } return ans; } };
二叉树中序遍历
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : vector<int > ans; vector<int > inorderTraversal (TreeNode* root) { dfs (root); return ans; } void dfs (TreeNode *root) { if (!root) return ; dfs (root->left); ans.push_back (root->val); dfs (root->right); } };
用栈模拟递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : vector<int > ans; stack<pair<TreeNode*, int >> stk; vector<int > inorderTraversal (TreeNode* root) { stk.push ({root, 0 }); while (stk.size ()) { if (stk.top ().first == nullptr ) { stk.pop (); continue ; } auto &t = stk.top ().second; auto now = stk.top ().first; if (t == 0 ) { stk.push ({now->left, 0 }); t = 1 ; } else if (t == 1 ) { ans.push_back (now->val); stk.push ({now->right, 0 }); t = 2 ; } else { stk.pop (); } } return ans; } };
沿着最左侧通路,自底向上依次访问沿途节点及其右子树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : vector<int > ans; vector<int > inorderTraversal (TreeNode* root) { stack<TreeNode *> stk; while (root || stk.size ()) { while (root) { stk.push (root); root = root->left; } root = stk.top (); stk.pop (); ans.push_back (root->val); root = root->right; } return ans; } };
二叉树后序遍历
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : vector<int > ans; vector<int > postorderTraversal (TreeNode* root) { dfs (root); return ans; } void dfs (TreeNode *root) { if (!root) return ; dfs (root->left); dfs (root->right); ans.push_back (root->val); } };
最高左侧可见叶节点(HLVFL)即为后序遍历首先访问的节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : vector<int > postorderTraversal (TreeNode* root) { vector<int > ans; if (!root) return ans; stack<TreeNode*> stk; stk.push (root); auto now = root; while (stk.size ()) { auto nxt = stk.top (); if (now != nxt->left && now != nxt->right) { while (nxt) { if (nxt->left) { if (nxt->right) stk.push (nxt->right); stk.push (nxt->left); nxt = nxt->left; } else if (nxt->right) { stk.push (nxt->right); nxt = nxt->right; } else break ; } } now = nxt; stk.pop (); ans.push_back (now->val); } return ans; } };
先求(根,右,左),可使用沿右侧分支写法,再反转成(左,右,根)的后序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution {public : vector<int > postorderTraversal (TreeNode* root) { vector<int > ans; stack<TreeNode*> stk; while (root || stk.size ()) { while (root) { ans.push_back (root->val); stk.push (root); root = root->right; } root = stk.top ()->left; stk.pop (); } reverse (ans.begin (), ans.end ()); return ans; } };
链表头部插入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : vector<int > postorderTraversal (TreeNode* root) { list<int > ans; stack<TreeNode*> stk; if (!root) return {ans.begin (), ans.end ()}; stk.push (root); while (stk.size ()) { auto now = stk.top (); stk.pop (); ans.push_front (now->val); if (now->left) stk.push (now->left); if (now->right) stk.push (now->right); } return {ans.begin (), ans.end ()}; } };
二叉树层次遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : vector<vector<int >> levelOrder (TreeNode* root) { vector<vector<int >> ans; queue<TreeNode*> q; if (root) q.push (root); while (q.size ()) { vector<int > level; int len = q.size (); while (len--) { auto t = q.front (); q.pop (); level.push_back (t->val); if (t->left) q.push (t->left); if (t->right) q.push (t->right); } ans.push_back (level); } return ans; } };
二叉树生成
关键在于确定根节点
给定一棵树的前序遍历 preorder
与中序遍历 inorder
。请构造二叉树并返回其根节点。
示例 1:
1 2 Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] Output: [3,9,20,null,null,15,7]
示例 2:
1 2 Input: preorder = [-1], inorder = [-1] Output: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder
和 inorder
均无重复元素
inorder
均出现在 preorder
preorder
保证为二叉树的前序遍历序列
inorder
保证为二叉树的中序遍历序列
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : unordered_map<int , int > pos; TreeNode* buildTree (vector<int >& preorder, vector<int >& inorder) { int n = preorder.size (); for (int i = 0 ; i < n; ++i) pos[inorder[i]] = i; return build (preorder, inorder, 0 , n - 1 , 0 , n - 1 ); } TreeNode* build (vector<int >& preorder, vector<int >& inorder, int pl, int pr, int il, int ir) { if (pl > pr) return nullptr ; auto root = new TreeNode (preorder[pl]); int mid = pos[root->val], llen = mid - il, rlen = ir - mid; root->left = build (preorder, inorder, pl + 1 , pl + llen, il, mid - 1 ); root->right = build (preorder, inorder, pl + llen + 1 , pr, mid + 1 , ir); return root; } };
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
1 2 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : unordered_map<int , int > pos; TreeNode* buildTree (vector<int >& inorder, vector<int >& postorder) { for (int i = 0 ; i < inorder.size (); ++i) pos[inorder[i]] = i; return build (inorder, postorder, 0 , inorder.size () - 1 , 0 , postorder.size () - 1 ); } TreeNode* build (vector<int > &inorder, vector<int > &postorder, int il, int ir, int pl, int pr) { if (il > ir) return nullptr ; auto root = new TreeNode (postorder[pr]); auto mid = pos[root->val], llen = mid - il, rlen = ir - mid; root->left = build (inorder, postorder, il, mid - 1 , pl, pl + llen - 1 ); root->right = build (inorder, postorder, mid + 1 , ir, pr - rlen, pr - 1 ); return root; } };
给你一个整数数组 nums
,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
1 2 3 输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:
1 2 3 输入:nums = [1,3] 输出:[3,1] 解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
按 严格递增 顺序排列
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : TreeNode* sortedArrayToBST (vector<int >& nums) { return build (nums, 0 , nums.size () - 1 ); } TreeNode* build (vector<int > &nums, int l, int r) { if (l > r) return nullptr ; int mid = l + r >> 1 ; auto root = new TreeNode (nums[mid]); root->left = build (nums, l, mid - 1 ); root->right = build (nums, mid + 1 , r); return root; } };
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树_每个节点_ 的左右两个子树的高度差的绝对值不超过 1。
示例:
1 2 3 4 5 6 7 8 给定的有序链表: [-10, -3, 0, 5, 9], 一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树: / \ -3 9 / / -10 5
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : TreeNode* sortedListToBST (ListNode* head) { if (!head) return nullptr ; int n = 0 ; for (auto p = head; p; p = p->next) ++n; if (n == 1 ) return new TreeNode (head->val); int mid = n / 2 ; auto cur = head; for (int i = 0 ; i < mid - 1 ; ++i) cur = cur->next; auto now = cur->next; cur->next = nullptr ; auto root = new TreeNode (now->val); root->left = sortedListToBST (head); root->right = sortedListToBST (now->next); return root; } };
难度中等 1099
给你一个整数 n
,请你生成并返回所有由 n
个节点组成且节点值从 1
到 n
互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
示例 1:
1 2 输入:n = 3 输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]
示例 2:
提示:
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : vector<TreeNode*> generateTrees (int n) { return dfs (1 , n); } vector<TreeNode*> dfs (int l, int r) { if (l > r) return {nullptr }; vector<TreeNode*> ans; for (int i = l; i <= r; ++i) { auto left = dfs (l, i - 1 ), right = dfs (i + 1 , r); for (auto l : left) { for (auto r : right) { auto root = new TreeNode (i); root->left = l, root->right = r; ans.push_back (root); } } } return ans; } };