代碼隨想錄算法訓練營|第二十天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树。刷题心得(c++)

目录

讀題

654.最大二叉树

自己看到题目的第一想法

617.合并二叉树

自己看到题目的第一想法

700.二叉搜索树中的搜索

自己看到题目的第一想法

98.验证二叉搜索树

自己看到题目的第一想法

看完代码随想录之后的想法

654.最大二叉树 - 實作

思路

Code

617.合并二叉树 - 實作

思路

Code

700.二叉搜索树中的搜索 - 實作

思路

遞迴

迭代

Code

遞迴代碼

迭代代碼

98.验证二叉搜索树 - 實作

思路

錯誤思路

正確思路

Code

錯誤代碼

正確代碼

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料

详细布置

654.最大二叉树

617.合并二叉树

700.二叉搜索树中的搜索

98.验证二叉搜索树


讀題

654.最大二叉树

自己看到题目的第一想法

看完這個題目之後,想到的是上周在做中序配合前序的,只是這一次的rootvalue固定為該序列的最大值,想像成是切割點應該會比較好想。原本是會切成左前序以及右前序數組,現在改成切左max點以及右max點

617.合并二叉树

自己看到题目的第一想法

這題我去想的是最大二叉數,其實我們本質上還是在構造一棵樹,只是中間節點固定,那要做的只是判斷左右是否為空,假設都為空直接return NULL, 只要有一方為空就直接return 不為空的節點,假設都為空,那接下來就是前序遍歷,先處理中間節點,將兩個節點的數值相加之後,就處理左節點跟右節點,分別往下遞迴,最後return root。

其實也不一定要前序遍歷,但就是這樣子做可以在建立root節點的同時,處理兩個數的相加會比較方便,但其實後序或中序也可以做,只是代碼會比較不簡潔。

700.二叉搜索树中的搜索

自己看到题目的第一想法

這題不難,二叉搜索樹的做法就是左樹比較小右樹比較大,那利用這個特性,假設為空return NULL

假設找到了,就return root, 不為空則根據大還是小選擇要遞迴哪個部份

假設是迭代的話,大致想法還是一樣,只是改為不用都return 而是假設root pop 出來的值根據大於小於等於進行對應的判斷,值到root為空return NULL

98.验证二叉搜索树

自己看到题目的第一想法

一開始覺得不難,但是後面有些比較奇特的二叉樹比如[1,null,1] 以及 [2,2,2],我的程式就會判斷錯誤,原本的想法是用迭代,感覺比較直覺,但用完之後還是錯誤,想不太透

看完代码随想录之后的想法

這題我看完遞迴以及迭代的做法,目前想只先用遞迴來理解,先不追求迭代也要馬上理解,在遞迴的部分有兩點之前沒有釐清

  1. 在二叉搜索樹中,用中序遍歷得出的數組會是單調遞增
  2. 深度遍歷要用Stack來實現,而不是層序遍歷

這兩點沒有釐清,導致寫出奇怪的程式碼,在這裡沒有想到雙指針又出現,但想像整體的中序遍歷展開後,的確用雙指針可以解決,而遞迴則是在一開始一路往左邊走,直到葉節點,之後再處理中間節點,最後在處理右節點,整體思路還是比較清晰的。

654.最大二叉树 - 實作

思路

  1. 尋找max點
  2. 假設max == -1 return NULL
  3. root = max
  4. 根據max點找到數組的下標(找切割點)
  5. 分成左右樹組
  6. root → left = 左遞迴
  7. root → right = 右遞迴
  8. return root

Code

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector& nums) {
       //定義max 為 INT_MIN
       if(nums.size() == 0) return NULL;
       int max = INT_MIN;
       int delimiter = 0;
       //尋找max值
       for(int i = 0; i < nums.size() ; i++) {
           if(nums[i] > max){
            max = nums[i];
            delimiter = i;
           }
       }
       //root = max;
       TreeNode* root = new TreeNode(max);
       //切割左右
       vector left_nums(nums.begin(), nums.begin() + delimiter);
       vector right_nums(nums.begin() + delimiter + 1, nums.end());

       //左右遞迴
       root->left = constructMaximumBinaryTree(left_nums);
       root->right = constructMaximumBinaryTree(right_nums);

       return root;
    }
};

617.合并二叉树 - 實作

思路

  1. 判斷root1&2是否為空,如果為空則return NULL
  2. 判斷是否其中一邊為空,如果有一邊為空則return 不為空的那邊
  3. 新建節點root並把roo1&root2的val相加後存入
  4. 左樹遞迴
  5. 右樹遞迴
  6. return NULL;

Code

**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(!root1 && !root2) return NULL;
        if(root1 && !root2) return root1;
        if(!root1 && root2) return root2;
        
        TreeNode* root = new TreeNode(root1->val + root2->val);

        root->left = mergeTrees(root1->left, root2->left);
        root->right = mergeTrees(root1->right, root2->right);
        
        return root;

    }
};

700.二叉搜索树中的搜索 - 實作

思路

遞迴

  1. root為空 return NULL
  2. root == val return root
  3. root > val 往左遞迴,否則往右遞迴

迭代

  1. while 循環,循環條件root不為空
  2. root→val == val return root;
  3. root→val > val root = root→left 否則 root = root→right
  4. 結束循環沒有找到,return NULL;

Code

遞迴代碼

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root == NULL) return NULL;
        if(root->val == val) return root;
        if(root->val > val) return searchBST(root->left, val);
        else return searchBST(root->right, val);
        
    }
};

迭代代碼

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while(root!=NULL) {
            if(root->val == val) return root;
            if(root->val > val) root = root->left;
            else root = root->right;
        }
        return NULL;
    }
};

98.验证二叉搜索树 - 實作

思路

錯誤思路

  1. 建立一個que進行層序遍歷
  2. 比較左右大小,假設不符合條件直接false
  3. 如果能通過則true

錯誤點: 沒有搞清楚二叉搜索樹的特性,以及深度遍歷要用Stack

正確思路

  1. 建立一個pre_node,用來與後一個node比較
  2. 如果root == NULL 代表沒有樹或走到葉子節點,return true;
  3. 中序遍歷
    1. 左遞迴
    2. 處理中間節點,如果pre != null 且 pre ≥ root return false
    3. 把pre改為後一個節點
    4. 遞迴右樹
    5. return 左右的結果

Code

錯誤代碼

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        queue que;
        if(root != NULL) que.push(root);
        while(!que.empty()) {
            int size = que.size();
            while(size--) {
                TreeNode* node = que.front();
                que.pop();
                if(node->left && (node->val > node->left->val)) que.push(node->left);
                else if(node->left && !(node->val > node->left->val))return false;
                if(node->right && (node->val < node->right->val)) que.push(node->right);
                else if(node->right && !(node->val < node->right->val))return false;
            }
        }
        return true;
    }
};

正確代碼

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* pre_node = NULL;
    bool isValidBST(TreeNode* root) {
        if(root == NULL) return true;
        bool left = isValidBST(root->left);
        if(pre_node != NULL && pre_node->val >= root->val) return false;
        pre_node = root;
        bool right = isValidBST(root->right);
        return left && right;
    }
};

總結

自己实现过程中遇到哪些困难

今天整體實現難度不高,主要是對驗證二叉搜索樹,自己對於二叉搜索樹的特性不瞭解,導致使用了錯誤的思路以及方法去實踐

今日收获,记录一下自己的学习时长

今天大概學了2hr ,但前兩題沒有去看卡哥的理解方式,時間比較晚了,如果自己能解出來,就先暫時沒看了。

相關資料

● 今日学习的文章链接和视频链接

详细布置

654.最大二叉树

题目链接/文章讲解:https://programmercarl.com/0654.最大二叉树.html

视频讲解:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili

617.合并二叉树

题目链接/文章讲解:https://programmercarl.com/0617.合并二叉树.html

视频讲解:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

700.二叉搜索树中的搜索

题目链接/文章讲解: https://programmercarl.com/0700.二叉搜索树中的搜索.html

视频讲解:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili

98.验证二叉搜索树

题目链接/文章讲解:https://programmercarl.com/0098.验证二叉搜索树.html

视频讲解:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili

你可能感兴趣的:(算法,c++,leetcode,数据结构,开发语言)