代碼隨想錄算法訓練營|第二十一天|530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先。刷题心得(c++)

目录

讀題

530.二叉搜索树的最小绝对差

自己看到题目的第一想法

501.二叉搜索树中的众数

自己看到题目的第一想法

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

236. 二叉树的最近公共祖先

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

530.二叉搜索树的最小绝对差 - 實作

思路

Code

501.二叉搜索树中的众数 - 實作

思路

一開始自己解的思路

代碼隨想錄看完後思路

Code

一開始自己解的思路

代碼隨想錄看完後思路

236. 二叉树的最近公共祖先 - 實作

思路

Code

總結

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

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

相關資料

530.二叉搜索树的最小绝对差

501.二叉搜索树中的众数

236. 二叉树的最近公共祖先


讀題

530.二叉搜索树的最小绝对差

自己看到题目的第一想法

這題看到雙指針的用法,其實整體不難,因為BST的特性會是單調遞增,利用這個特性使用雙指針法前後相減,假設min值大於這個相減的值,代表這個是當前最小的絕對差,之後持續遍歷值到最後一個數值,return min即可。

501.二叉搜索树中的众数

自己看到题目的第一想法

看到BST題目我首先想到中序遍歷、單調遞增,那我最後的Result 也會是單調遞增,但實際上要怎麼去實行想法也有想到可以比對前後之值,但實現起來並沒有那麼簡單,想了三十分鐘,一直會推翻自己的想法,原本想直接看代碼隨想錄,但是卡哥在影片中說,建議自己先試過,因為其實題目真的不難,但是那個思維比較困難,結果自己一步步去嘗試,去試錯,結果還真讓我找到遞迴只遍歷一次的解法,說難吧,不難,說不難吧也不能這麼說,但大致的想法跟我前面所提到的重點一樣,中序遍歷、單調遞增,以及count、maxCount的組合,來思考。

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

大致思路差不多,只是我是直接在主函數內進行實現,卡哥是有額外再寫一個函數,不過看完後學到了以下兩點

  1. 將pre = root往外移,減少代碼行數
  2. 學到了一個C++函數 clear() 把數組清空

236. 二叉树的最近公共祖先

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

看完之後雖然代碼不難,但理解上還需要花一點時間來理解但可以理解為三個部分

  1. 後序遍歷,由下往上開始查找
  2. 透過回朔,找出所需的節點
  3. 情況一 p q 分別在左右子樹、情況二 p 或 q 剛好是另一個的公共節點

530.二叉搜索树的最小绝对差 - 實作

思路

  1. 建立pre node以及min 值
  2. 假設root == NULL return min;
  3. 中序遍歷
    1. 左: 假設左節點存在左遍歷
    2. 中: 假設pre節點不為空 並且 min > (root→val - pre→val) 反過來還要在加絕對值,利用單調遞增的規則,由後減前
    3. 右: 假設右節點存在右遍歷
  4. return min;

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* pre = NULL;
    int min = INT_MAX;
    int getMinimumDifference(TreeNode* root) {
        if(!root) return min;
        if(root->left) getMinimumDifference(root->left);
        if(pre != NULL && (min > (root->val - pre->val))) min = root->val - pre->val;
        pre = root;
        if(root->right) getMinimumDifference(root->right); 
        return min;
    }
};

501.二叉搜索树中的众数 - 實作

思路

一開始自己解的思路

  1. 建立result數組、count=0(紀錄目前一樣的次數)、maxCount=0(最大的重複次數)
  2. 中序遍歷
    1. 左: 左遞迴到最左的葉子節點
    2. 中: 處理中間的數值
      1. 假設pre == NULL,pre = root & 將當前的value加入到result當中
      2. 假設pre ≠ NULL
        1. 比較pre 以及 root 假設不一致,count 回到初始值,並更新pre的位置 (pre = root)
        2. 如果一致則count++(這裡的pre的位置並未更新,可以想像成滑動窗口)
      3. 假設count > maxCount
        1. 更新maxCount
        2. result resize 為0
        3. 將當前節點加入到result當中
      4. 假設count == maxCount → 代表找到一樣高頻的節點
        1. 將目前數值加入到result數組當中
    3. 右:右遞迴
  3. return result.

代碼隨想錄看完後思路

  1. 建立result數組、count=0(紀錄目前一樣的次數)、maxCount=0(最大的重複次數)
  2. 設立終止條件 if(root == NULL) return result
  3. 中序遍歷
    1. 左: 左遞迴到最左的葉子節點
    2. 中: 處理中間的數值
      1. 假設pre == NULL,count = 0 將當前的value加入到result當中
      2. 假設pre ≠ NULL
        1. 比較pre 以及 root 假設不一致,count 回到初始值,
        2. 如果一致則count++
      3. 假設count > maxCount
        1. 更新maxCount
        2. result clear
        3. 將當前節點加入到result當中
      4. 假設count == maxCount → 代表找到一樣高頻的節點
        1. 將目前數值加入到result數組當中
      5. 更新pre的位置 (pre = root)
    3. 右:右遞迴
  4. return result.

Code

一開始自己解的思路

class Solution {
public:
    TreeNode* pre = NULL;
    int maxCount = 0;
    int count = 0;
    vector result;
    vector findMode(TreeNode* root) {
        if(root->left)findMode(root->left);
        if(pre != NULL){
            if(pre->val != root->val){
                count = 0;
                pre = root;
            } else count++;
            if(count > maxCount){
                maxCount = count;
                result.resize(0);
                result.push_back(root->val);
            } else if (count == maxCount) {
                result.push_back(root->val);
            }
            
        } else {
            pre = root;
            result.push_back(pre->val);
        }
        if(root->right)findMode(root->right);

        return result;
    }
};

代碼隨想錄看完後思路

class Solution {
public:
    TreeNode* pre = NULL;
    int maxCount = 0;
    int count = 0;
    vector result;
    vector findMode(TreeNode* root) {
        if(root == NULL) return result;
        if(root->left)findMode(root->left);
        if(pre != NULL){
            if(pre->val != root->val){
                count = 0;
            } else count++;
            if(count > maxCount){
                maxCount = count;
                result.clear();
                result.push_back(root->val);
            } else if (count == maxCount) {
                result.push_back(root->val);
            }
        } else {
            count = 0;
            result.push_back(root->val);
        }
        pre = root;
        if(root->right)findMode(root->right);

        return result;
    }
};

236. 二叉树的最近公共祖先 - 實作

思路

  1. 終止條件
    1. if root == null return null
    2. if root = p || q return root → return 當前所遍歷到的節點,也就是root
  2. 後序遍歷
    1. 左 TreeNode* left = 遞迴
    2. 右 TreeNode* right = 遞迴
      1. left && right 不為空 return root → 代表左右子樹都有p或q
      2. left or right 其中一個為空,返回不為空的那邊 → 代表左右節點可能都在左或右 (題目已告知一定會有pq)
      3. 假設都為空 return null (代表這棵樹沒有公共節點

Code

/**
 * 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == q || root == p || root == NULL) return root;
        
        //左
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        //右
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        //中
        if(left != NULL && right != NULL) return root;
        if (left != NULL && right == NULL) return left;
        else if (left == NULL && right != NULL) return right;
        else return NULL;

    }
};

總結

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

今天在解題的過程中,最困難的在公共祖先,其次就是二叉搜索樹中的眾數,但也不到完全無法理解,整體而言還是蠻舒爽的,尤其是自己解出二叉搜索樹中的眾數。

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

今天我大概學習三小時左右

其實在第二題我一度要放棄,但是看到卡哥的影片講解第一段的時候,說建議還是自己做過一次,就花了大概一個小時,靜下心來慢慢做,結果還真的完成了,真的很開心

相關資料

530.二叉搜索树的最小绝对差

题目链接/文章讲解:https://programmercarl.com/0530.二叉搜索树的最小绝对差.htmlicon-default.png?t=N7T8https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE.html

视频讲解:二叉搜索树中,需要掌握如何双指针遍历!| LeetCode:530.二叉搜索树的最小绝对差_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com, 这里刷题顺序,详细题解,应有尽有!, 视频播放量 13201、弹幕量 201、点赞数 363、投硬币枚数 225、收藏人数 73、转发人数 21, 视频作者 代码随想录, 作者简介 我是Carl,哈工大师兄,先后在腾讯和百度从事一线技术研发的程序员,公众号「代码随想录」,相关视频:动态规划开更了!| LeetCode:746. 使用最小花费爬楼梯,不仅双指针,还有代码技巧可以惊艳到你! | LeetCode:501.二叉搜索树中的众数,单调队列正式登场!| LeetCode:239. 滑动窗口最大值,带你学透完全背包问题! 和 01背包有什么差别?遍历顺序上有什么讲究?,双指针法经典题目 | LeetCode:977.有序数组的平方,讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历,贪心算法理论基础!,调整二叉树的结构最难!| LeetCode:450.删除二叉搜索树中的节点,我更完了,你看完了吗?,带你学透回溯算法-组合问题(对应力扣题目:77.组合)| 回溯法精讲!icon-default.png?t=N7T8https://www.bilibili.com/video/BV1DD4y11779

501.二叉搜索树中的众数

https://programmercarl.com/0501.二叉搜索树中的众数.html

视频讲解:不仅双指针,还有代码技巧可以惊艳到你! | LeetCode:501.二叉搜索树中的众数_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com, 这里刷题顺序,详细题解,应有尽有!, 视频播放量 63511、弹幕量 301、点赞数 1152、投硬币枚数 553、收藏人数 1168、转发人数 65, 视频作者 代码随想录, 作者简介 我是Carl,哈工大师兄,先后在腾讯和百度从事一线技术研发的程序员,公众号「代码随想录」,相关视频:公司新来00后写的代码,看到这段话我差点笑出猪叫,【labuladong】数组双指针技巧全面汇总,这代码保无Bug么?,10分钟学会哈希表,编程学生提交的作业,老师和同学看到后都沉默了,不会左值右值引用等于不会 C++!,真实的程序员敲代码,LeetCode刷题分享 | 零基础刷算法题,当你写了个BUG还能运行,它就成了一个游戏!,LeetCode407 3D接雨水,最最臭名昭著劝退题,真的很难吗?icon-default.png?t=N7T8https://www.bilibili.com/video/BV1fD4y117gp

236. 二叉树的最近公共祖先

https://programmercarl.com/0236.二叉树的最近公共祖先.html

视频讲解:自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com, 这里刷题顺序,详细题解,应有尽有!, 视频播放量 23852、弹幕量 470、点赞数 988、投硬币枚数 696、收藏人数 196、转发人数 33, 视频作者 代码随想录, 作者简介 我是Carl,哈工大师兄,先后在腾讯和百度从事一线技术研发的程序员,公众号「代码随想录」,相关视频:二叉树的最近公共祖先,剑指68 II 二叉树的最近公共祖先,【不看后悔的一道题】LeetCode 236题 二叉树的最近公共祖先 二叉树里的最强王者 不容错过的笔试必考题 C++编程详解 思维导图拆解算法思路,236. 二叉树的最近公共祖先 Lowest Common Ancestor of a Binary Tree【LeetCode 力扣官方题解】,算法面试,二叉树中两节点的最近公共祖先(LeetCode 236),23王道数据结构 150页13题 二叉树 寻找最近公共祖先,递归方法寻找二叉树任意的两个节点的最近公共祖先 含代码展示和思路讲解,数据结构-寻找二叉树两个结点的最近公共祖先,(自用视频)非递归后序遍历二叉树 公共祖先,23王道数据结构 134页05题 求二叉树公共祖先代码icon-default.png?t=N7T8https://www.bilibili.com/video/BV1jd4y1B7E2

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