目录
讀題
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],我的程式就會判斷錯誤,原本的想法是用迭代,感覺比較直覺,但用完之後還是錯誤,想不太透
看完代码随想录之后的想法
這題我看完遞迴以及迭代的做法,目前想只先用遞迴來理解,先不追求迭代也要馬上理解,在遞迴的部分有兩點之前沒有釐清
- 在二叉搜索樹中,用中序遍歷得出的數組會是單調遞增
- 深度遍歷要用Stack來實現,而不是層序遍歷
這兩點沒有釐清,導致寫出奇怪的程式碼,在這裡沒有想到雙指針又出現,但想像整體的中序遍歷展開後,的確用雙指針可以解決,而遞迴則是在一開始一路往左邊走,直到葉節點,之後再處理中間節點,最後在處理右節點,整體思路還是比較清晰的。
654.最大二叉树 - 實作
思路
- 尋找max點
- 假設max == -1 return NULL
- root = max
- 根據max點找到數組的下標(找切割點)
- 分成左右樹組
- root → left = 左遞迴
- root → right = 右遞迴
- 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<int>& 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<int> left_nums(nums.begin(), nums.begin() + delimiter);
vector<int> right_nums(nums.begin() + delimiter + 1, nums.end());
//左右遞迴
root->left = constructMaximumBinaryTree(left_nums);
root->right = constructMaximumBinaryTree(right_nums);
return root;
}
};
617.合并二叉树 - 實作
思路
- 判斷root1&2是否為空,如果為空則return NULL
- 判斷是否其中一邊為空,如果有一邊為空則return 不為空的那邊
- 新建節點root並把roo1&root2的val相加後存入
- 左樹遞迴
- 右樹遞迴
- 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.二叉搜索树中的搜索 - 實作
思路
遞迴
- root為空 return NULL
- root == val return root
- root > val 往左遞迴,否則往右遞迴
迭代
- while 循環,循環條件root不為空
- root→val == val return root;
- root→val > val root = root→left 否則 root = root→right
- 結束循環沒有找到,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.验证二叉搜索树 - 實作
思路
錯誤思路
- 建立一個que進行層序遍歷
- 比較左右大小,假設不符合條件直接false
- 如果能通過則true
錯誤點: 沒有搞清楚二叉搜索樹的特性,以及深度遍歷要用Stack
正確思路
- 建立一個pre_node,用來與後一個node比較
- 如果root == NULL 代表沒有樹或走到葉子節點,return true;
- 中序遍歷
- 左遞迴
- 處理中間節點,如果pre != null 且 pre ≥ root return false
- 把pre改為後一個節點
- 遞迴右樹
- 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<TreeNode*> 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