目录
讀題
530.二叉搜索树的最小绝对差
自己看到题目的第一想法
這題看到雙指針的用法,其實整體不難,因為BST的特性會是單調遞增,利用這個特性使用雙指針法前後相減,假設min值大於這個相減的值,代表這個是當前最小的絕對差,之後持續遍歷值到最後一個數值,return min即可。
501.二叉搜索树中的众数
自己看到题目的第一想法
看到BST題目我首先想到中序遍歷、單調遞增,那我最後的Result 也會是單調遞增,但實際上要怎麼去實行想法也有想到可以比對前後之值,但實現起來並沒有那麼簡單,想了三十分鐘,一直會推翻自己的想法,原本想直接看代碼隨想錄,但是卡哥在影片中說,建議自己先試過,因為其實題目真的不難,但是那個思維比較困難,結果自己一步步去嘗試,去試錯,結果還真讓我找到遞迴只遍歷一次的解法,說難吧,不難,說不難吧也不能這麼說,但大致的想法跟我前面所提到的重點一樣,中序遍歷、單調遞增,以及count、maxCount的組合,來思考。
看完代码随想录之后的想法
大致思路差不多,只是我是直接在主函數內進行實現,卡哥是有額外再寫一個函數,不過看完後學到了以下兩點
- 將pre = root往外移,減少代碼行數
- 學到了一個C++函數 clear() 把數組清空
236. 二叉树的最近公共祖先
看完代码随想录之后的想法
看完之後雖然代碼不難,但理解上還需要花一點時間來理解但可以理解為三個部分
- 後序遍歷,由下往上開始查找
- 透過回朔,找出所需的節點
- 情況一 p q 分別在左右子樹、情況二 p 或 q 剛好是另一個的公共節點
530.二叉搜索树的最小绝对差 - 實作
思路
- 建立pre node以及min 值
- 假設root == NULL return min;
- 中序遍歷
- 左: 假設左節點存在左遍歷
- 中: 假設pre節點不為空 並且 min > (root→val - pre→val) 反過來還要在加絕對值,利用單調遞增的規則,由後減前
- 右: 假設右節點存在右遍歷
- 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.二叉搜索树中的众数 - 實作
思路
一開始自己解的思路
- 建立result數組、count=0(紀錄目前一樣的次數)、maxCount=0(最大的重複次數)
- 中序遍歷
- 左: 左遞迴到最左的葉子節點
- 中: 處理中間的數值
- 假設pre == NULL,pre = root & 將當前的value加入到result當中
- 假設pre ≠ NULL
- 比較pre 以及 root 假設不一致,count 回到初始值,並更新pre的位置 (pre = root)
- 如果一致則count++(這裡的pre的位置並未更新,可以想像成滑動窗口)
- 假設count > maxCount
- 更新maxCount
- result resize 為0
- 將當前節點加入到result當中
- 假設count == maxCount → 代表找到一樣高頻的節點
- 將目前數值加入到result數組當中
- 右:右遞迴
- return result.
代碼隨想錄看完後思路
- 建立result數組、count=0(紀錄目前一樣的次數)、maxCount=0(最大的重複次數)
- 設立終止條件 if(root == NULL) return result
- 中序遍歷
- 左: 左遞迴到最左的葉子節點
- 中: 處理中間的數值
- 假設pre == NULL,count = 0 將當前的value加入到result當中
- 假設pre ≠ NULL
- 比較pre 以及 root 假設不一致,count 回到初始值,
- 如果一致則count++
- 假設count > maxCount
- 更新maxCount
- result clear
- 將當前節點加入到result當中
- 假設count == maxCount → 代表找到一樣高頻的節點
- 將目前數值加入到result數組當中
- 更新pre的位置 (pre = root)
- 右:右遞迴
- return result.
Code
一開始自己解的思路
class Solution {
public:
TreeNode* pre = NULL;
int maxCount = 0;
int count = 0;
vector<int> result;
vector<int> 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<int> result;
vector<int> 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. 二叉树的最近公共祖先 - 實作
思路
- 終止條件
- if root == null return null
- if root = p || q return root → return 當前所遍歷到的節點,也就是root
- 後序遍歷
- 左 TreeNode* left = 遞迴
- 右 TreeNode* right = 遞迴
- 中
- left && right 不為空 return root → 代表左右子樹都有p或q
- left or right 其中一個為空,返回不為空的那邊 → 代表左右節點可能都在左或右 (題目已告知一定會有pq)
- 假設都為空 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.二叉搜索树的最小绝对差
501.二叉搜索树中的众数
https://programmercarl.com/0501.二叉搜索树中的众数.html