日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode中二叉树相关题

發布時間:2024/4/11 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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++代碼:

    /*** 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* buildTree(vector<int>& preorder, vector<int>& inorder) {//遞歸分治//控制好邊界,剩下的交給遞歸return recursionBuild(preorder.begin(),preorder.end(),inorder.begin(),inorder.end());}//遞歸分治TreeNode* recursionBuild(vector<int>::iterator preBegin, vector<int>::iterator preEnd, vector<int>::iterator inBegin, vector<int>::iterator inEnd ){if(inEnd==inBegin) return NULL;TreeNode* cur = new TreeNode(*preBegin);//在中序遍歷數組中找前序遍歷的第一個節點,最為中序數組的左右子樹分界點auto root = find(inBegin,inEnd,*preBegin);//遞歸構造左右子樹cur->left = recursionBuild(preBegin + 1,preBegin + (root - inBegin) + 1,inBegin,root);cur->right = recursionBuild(preBegin + 1 + (root - inBegin),preEnd,root + 1,inEnd);return cur;} };

    第三題:恢復?棵 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中二叉树相关题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。