LeetCode中二叉树相关题
Leetcode中二叉樹相關題
二叉樹相關的題相對來說還是比較簡單的,都是套路
第一題:求二叉樹中最大路徑和
給定一個非空二叉樹,返回其最大路徑和。
本題中,路徑被定義為一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不一定經過根節點。
示例 1:
輸入: [1,2,3]1/ \2 3輸出: 6示例 2:
輸入: [-10,9,20,null,null,15,7]-10/ \9 20/ \15 7輸出: 42這就是個后序遍歷嘛
int ans = INT_MIN; int oneSideMax(TreeNode* root) {if (root == nullptr) return 0;int left = max(0, oneSideMax(root->left));int right = max(0, oneSideMax(root->right));ans = max(ans, left + right + root->val);return max(left, right) + root->val; }C++代碼:
/*** 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:int sum = INT_MIN;int maxPathSumchild(TreeNode* root){//遞歸出口if(root == nullptr){return 0;}//遞歸求 某個節點 的 左子樹 和 右子樹 的權值int left = max(0,maxPathSumchild(root->left));int right = max(0,maxPathSumchild(root->right));//檢查是否需要更新創建新的路徑,新路徑的權值是left + right + root->val,最后更新sumsum = max(sum,(left + right + root->val));//遞歸返回 到當前節點的一條最大路徑return max(left,right) + root->val;}int maxPathSum(TreeNode* root){maxPathSumchild(root);return sum;} };第二題:根據前序遍歷和中序遍歷的結果還原?棵?叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重復的數字。
例如,給出
前序遍歷 preorder = [3,9,20,15,7] 中序遍歷 inorder = [9,3,15,20,7] 返回如下的二叉樹:3/ \9 20/ \15 7限制:
- 0 <= 節點個數 <= 5000
直接看代碼:
TreeNode buildTree(int[] preorder, int preStart, int preEnd,int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inMap) {if(preStart > preEnd || inStart > inEnd) return null;TreeNode root = new TreeNode(preorder[preStart]);int inRoot = inMap.get(root.val);int numsLeft = inRoot - inStart;root.left = buildTree(preorder, preStart + 1, preStart + numsLeft,inorder, inStart, inRoot - 1, inMap);root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd,inorder, inRoot + 1, inEnd, inMap);return root; }這道題不難,看上一個例子就知道基本思想,重點是邊界控制問題
根據下面9張圖看一下例子當中二叉樹的構建過程
2.
3.
4.
5.
6.
7.
8.
9.
C++代碼:
第三題:恢復?棵 BST
二叉搜索樹中的兩個節點被錯誤地交換。
請在不改變其結構的情況下,恢復這棵樹。
示例 1:
輸入: [1,3,null,null,2]1/3\2輸出: [3,1,null,null,2]3/1\2示例 2:
輸入: [3,1,4,null,null,2]3/ \ 1 4/2輸出: [2,1,4,null,null,3]2/ \ 1 4/3這道題難點,是找到那兩個交換節點,把它交換過來就行了.
這里我們二叉樹搜索樹的中序遍歷(中序遍歷遍歷元素是遞增的)
如下圖所示, 中序遍歷順序是 4,2,3,1,我們只要找到節點4和節點1交換順序即可!
這里我們有個規律發現這兩個節點:
第一個節點,是第一個按照中序遍歷時候前一個節點大于后一個節點,我們選取前一個節點,這里指節點4;
第二個節點,是在第一個節點找到之后, 后面出現前一個節點大于后一個節點,我們選擇后一個節點,這里指節點1;
void traverse(TreeNode* node) {if (!node) return;traverse(node->left);if (node->val < prev->val) {s = (s == NULL) ? prev : s;t = node;}prev = node;traverse(node->right); }first記錄第一個被錯誤交換的節點指針,second記錄第二個被錯誤交換的節點指針,prev記錄在中序遍歷中上一個被遍歷到的節點指針;
通過比較當前節點的值和上一個節點的值來判斷其是否是first或者second;注意:若被錯誤交換的兩個節點在中序遍歷中是相鄰的兩個節點(相鄰是指以相鄰的順序被遍歷到),與不相鄰的區別;
完整代碼:
class Solution { private:TreeNode* first = nullptr;//指向第一個錯誤的節點TreeNode* second = nullptr;//指向第二個錯誤的節點TreeNode* pre = new TreeNode(INT_MIN);//相對于當前節點在中序遍歷下的上一個節點void helper(TreeNode* root){if(root == nullptr){return;}//中序遍歷helper(root->left);//注意全程只有兩個錯誤節點,所以下面的代碼才可以那樣寫//找到第一個節點才可以繼續找第二個錯誤節點,但是注意這兩個節點并不一定是相鄰的if(first == nullptr && pre->val > root->val){first = pre;}if(first != nullptr && pre->val > root->val){second = root;}pre = root;helper(root->right);} public:void recoverTree(TreeNode* root) {helper(root);swap(first->val,second->val);}};最后發現這不就是個中序遍歷嘛,
你看, Hard 難度的題?不過如此, ?且還這么有規律可循, 只要把框架寫出來, 然后往相應的位置加東?就?了, 這不就是思路嗎
總結
以上是生活随笔為你收集整理的LeetCode中二叉树相关题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下通用的Makefile
- 下一篇: 单调栈之Next Greater Num