目录
讀題
654.最大二叉树
自己看到题目的第一想法
617.合并二叉树
自己看到题目的第一想法
700.二叉搜索树中的搜索
自己看到题目的第一想法
98.验证二叉搜索树
自己看到题目的第一想法
看完代码随想录之后的想法
654.最大二叉树 - 實作
思路
Code
617.合并二叉树 - 實作
思路
Code
700.二叉搜索树中的搜索 - 實作
思路
遞迴
迭代
Code
遞迴代碼
迭代代碼
98.验证二叉搜索树 - 實作
思路
錯誤思路
正確思路
Code
錯誤代碼
正確代碼
總結
自己实现过程中遇到哪些困难
今日收获,记录一下自己的学习时长
相關資料
详细布置
654.最大二叉树
617.合并二叉树
700.二叉搜索树中的搜索
98.验证二叉搜索树
看完這個題目之後,想到的是上周在做中序配合前序的,只是這一次的rootvalue固定為該序列的最大值,想像成是切割點應該會比較好想。原本是會切成左前序以及右前序數組,現在改成切左max點以及右max點
這題我去想的是最大二叉數,其實我們本質上還是在構造一棵樹,只是中間節點固定,那要做的只是判斷左右是否為空,假設都為空直接return NULL, 只要有一方為空就直接return 不為空的節點,假設都為空,那接下來就是前序遍歷,先處理中間節點,將兩個節點的數值相加之後,就處理左節點跟右節點,分別往下遞迴,最後return root。
其實也不一定要前序遍歷,但就是這樣子做可以在建立root節點的同時,處理兩個數的相加會比較方便,但其實後序或中序也可以做,只是代碼會比較不簡潔。
這題不難,二叉搜索樹的做法就是左樹比較小右樹比較大,那利用這個特性,假設為空return NULL
假設找到了,就return root, 不為空則根據大還是小選擇要遞迴哪個部份
假設是迭代的話,大致想法還是一樣,只是改為不用都return 而是假設root pop 出來的值根據大於小於等於進行對應的判斷,值到root為空return NULL
一開始覺得不難,但是後面有些比較奇特的二叉樹比如[1,null,1] 以及 [2,2,2],我的程式就會判斷錯誤,原本的想法是用迭代,感覺比較直覺,但用完之後還是錯誤,想不太透
這題我看完遞迴以及迭代的做法,目前想只先用遞迴來理解,先不追求迭代也要馬上理解,在遞迴的部分有兩點之前沒有釐清
這兩點沒有釐清,導致寫出奇怪的程式碼,在這裡沒有想到雙指針又出現,但想像整體的中序遍歷展開後,的確用雙指針可以解決,而遞迴則是在一開始一路往左邊走,直到葉節點,之後再處理中間節點,最後在處理右節點,整體思路還是比較清晰的。
/**
* 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;
}
};
**
* 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;
}
};
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;
}
};
錯誤點: 沒有搞清楚二叉搜索樹的特性,以及深度遍歷要用Stack
/**
* 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 ,但前兩題沒有去看卡哥的理解方式,時間比較晚了,如果自己能解出來,就先暫時沒看了。
● 今日学习的文章链接和视频链接
题目链接/文章讲解:https://programmercarl.com/0654.最大二叉树.html
视频讲解:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili
题目链接/文章讲解:https://programmercarl.com/0617.合并二叉树.html
视频讲解:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili
题目链接/文章讲解: https://programmercarl.com/0700.二叉搜索树中的搜索.html
视频讲解:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili
题目链接/文章讲解:https://programmercarl.com/0098.验证二叉搜索树.html
视频讲解:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili