目录
讀題
110.平衡二叉树
自己看到题目的第一想法
看完代码随想录之后的想法
257. 二叉树的所有路径
自己看到题目的第一想法
看完代码随想录之后的想法
404.左叶子之和
自己看到题目的第一想法
看完代码随想录之后的想法
110.平衡二叉树 - 實作
思路
錯誤思路
正確思路
Code
錯誤代碼
正確代碼
257. 二叉树的所有路径 - 實作
思路
Code
思考
404.左叶子之和 - 實作
思路
Code
總結
自己实现过程中遇到哪些困难
今日收获,记录一下自己的学习时长
相關資料
110.平衡二叉树
257. 二叉树的所有路径
404.左叶子之和
看到完整題目,平衡二叉樹就是左右子樹的高度差不能超過一,假設超過一就不是,那其實跟求二叉樹的最小深度一樣,找出左右子樹的深度,之後進行比較,假設大於1 return false,小於等於1 return true;
看完之後,我發現我對於高度跟深度有誤解,高度的話要用后序遍歷(下到上)來看,深度要用前序遍歷(上到下)來看,在求最大深度的時候,因為其實也可以看成求二叉樹的從葉子節點到根結點的高度,所以才可以使用前序遍歷。所以在遍歷的邏輯上以及思維上其實都進入了誤區,需要再找時間釐清二叉樹的想法
看到第一眼是想我要怎麼給出結果,另外一個是我的左子樹要怎麼去跑,看得有點矇,直接看代碼隨想錄
看完還是對回朔有點矇,這題代碼看完code之後有點理解思路,但是如果要更深入的解析,我需要花更久的時間才能做,但以目前的想法來說,因為卡哥有用一個取用地址的做法,在精簡版的代碼當中,path可以理解為區域變數,到了下一個遞迴就不見了,而完整版可以想像成全域變數,如果不pop,則異常,因為路徑仍在,我先寫完整版,協助我來理解這道問題
看到之後感覺有點像所有路徑,一樣是到葉子節點,但是這邊要判斷說是不是左葉子節點,可能就要先去理解一下甚麼是左葉子節點了。
看完之後,的確跟一般的二叉樹操作有所差異,但整體來說還是不難,只是我需要更多的時間來釐清這周二叉樹的部分。
錯誤點: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。我這只有比較root節點,並沒有去比較全部的節點
class Solution {
public:
int getdepth(TreeNode* cur) {
if(cur == NULL) return 1;
int leftdepth = getdepth(cur->left);
int rightdepth = getdepth(cur->right);
return 1 + max(leftdepth, rightdepth);
}
bool isBalanced(TreeNode* root) {
if(root == NULL) return 1;
int rightdepth = getdepth(root->right);
int leftdepth = getdepth(root->left);
int gap = 0;
if(rightdepth > leftdepth) gap = rightdepth - leftdepth;
else gap = leftdepth - rightdepth;
return gap <= 1 ? true:false;
}
};
class Solution {
public:
int gethight(TreeNode* cur) {
if(cur == NULL) return 0;
int lefthight = getdepth(cur->left);
if(lefthight == -1) return -1;
int righthight = getdepth(cur->right);
if(righthight == -1) return -1;
int result = 0;
if(abs(lefthight - righthight) > 1) result = -1;
else result = 1 + max(lefthight,righthight);
return result;
}
bool isBalanced(TreeNode* root) {
return gethight(root) == -1 ? false : true;
}
};
class Solution {
public:
void traversal(TreeNode* cur, vector&path, vector& result) {
path.push_back(cur->val);
if(cur->left == NULL && cur->right ==NULL) {
string sPath;
for(int i = 0; i < path.size()-1; i++) {
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
result.push_back(sPath);
}
if(cur->left) {
traversal(cur->left, path, result);
path.pop_back();
}
if(cur->right) {
traversal(cur->right, path, result);
path.pop_back();
}
}
vector binaryTreePaths(TreeNode* root) {
vector result;
vector path;
if(root == NULL) return result;
traversal(root, path, result);
return result;
}
};
寫的過程中,不斷的去思考,突然理解了回朔的過程,path是vector,底層是dequeue,在這個過程中,假設我一直走左子樹,那我到底的時候,我的path就是在左子樹的第一個葉子節點那我回朔的時候就要path就要pop一個葉子,假設有右節點下一個就會進到右節點,右節點結束之後,就會跳出,之後又把path給pop出來,這樣就達到回朔的目的了。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root == NULL) return 0;
if(root->left == NULL && root->right == NULL) return 0;
int leftValue = sumOfLeftLeaves(root->left);
if(root->left && !root->left->left && !root->left->right) {
leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right);
int sum = leftValue + rightValue;
return sum;
}
};
今天在實現的過程中發現自己對於二叉樹的知識還是不足,經驗上也是,所以在看到這三題的時候,其實很多時候是不清楚的,現在還需要再花時間理解
今天至少知道自己對於前中後序的用法還是不太清楚以及高度與深度的求法,讓我可以在接下來兩天的假期中好好去理解
● 今日学习的文章链接和视频链接
题目链接/文章讲解/视频讲解:https://programmercarl.com/0110.平衡二叉树.html
题目链接/文章讲解/视频讲解:https://programmercarl.com/0257.二叉树的所有路径.html
题目链接/文章讲解/视频讲解:https://programmercarl.com/0404.左叶子之和.html