在此非常感谢“代码随想录”的通俗易懂的总结!
(致敬叶师傅和李小龙)
“我不害怕曾经练过一万种踢法的人,但我害怕一种踢法练过一万次的人”(by 叶师傅的徒弟Bruce Lee)
今天继续打5道,加油,冲冲冲!
具体题目
题目1:257. 二叉树的所有路径
题目描述:
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一一个路径在进入另一个路径。
前序遍历以及回溯的过程如图:
C++代码
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& path,vector<string>& 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);
return;
}
if(cur->left){
traversal(cur->left,path,result);
path.pop_back();//回溯
}
if(cur->right){
traversal(cur->right,path,result);
path.pop_back();//回溯
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
traversal(root,path,result);
return result;
}
};
题目2:100. 相同的树
题目描述:
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
C++代码:
方法一、递归方法
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL && q!=NULL) return false;
else if(q==NULL && p!=NULL) return false;
else if(p==NULL && q==NULL) return true;
else if(p->val != q->val) return false;//一定要写在前三行之后,因为有可能遇到p或者q为NULL
else return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
};
方法二、迭代方法(队列)
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL && q==NULL) return true;
if(p==NULL || q==NULL) return false;
queue<TreeNode*> que;
que.push(p);
que.push(q);
while(!que.empty()){
TreeNode* tree1=que.front();
que.pop();
TreeNode* tree2=que.front();
que.pop();
if((tree1==NULL) && (tree2==NULL)) continue;
if((tree1==NULL || tree2==NULL || (tree1->val!=tree2->val))) return false;
que.push(tree1->left);
que.push(tree2->left);
que.push(tree1->right);
que.push(tree2->right);
}
return true;
}
};
题目3:572. 另一个树的子树
题目描述:
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
示例 1:
示例 2:
C++代码:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q) return true;
else if(!p || !q) return false;
else if(p->val != q->val) return false;
else return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
bool isSubtree(TreeNode* s, TreeNode* t) {
if(!s && !t) return true;
else if(!s || !t) return false;
// else if(s->val != t->val) return false;
else return isSameTree(s,t) || isSubtree(s->left,t) || isSubtree(s->right,t);
}
};
题目4:404. 左叶子之和
题目描述:
计算给定二叉树的所有左叶子之和。
示例:
这道题的关键是如何判断左叶子——如果左节点不为空,且左节点没有左右孩子,那么这个节点就是左叶子
「判断当前节点是不是左叶子不好判断,必须要通过节点的父节点来判断其左孩子是不是左叶子。」
如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子
C++代码:
方法一、递归方法
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==NULL) return 0;
int sumleft=0;
if(root->left!=NULL && root->left->left==NULL && root->left->right==NULL) sumleft=root->left->val;
return sumleft+sumOfLeftLeaves(root->left)+sumOfLeftLeaves(root->right);
}
};
方法二、迭代之前序遍历
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==NULL) return 0;
stack<TreeNode*> st;
st.push(root);
int sumleft=0;
while(!st.empty()){
TreeNode* cur=st.top();
st.pop();
if(cur->left!=NULL && cur->left->left==NULL && cur->left->right==NULL) sumleft+=cur->left->val;
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}
return sumleft;
}
};
题目5:513. 找树左下角的值
题目描述:
给定一个二叉树,在树的最后一行找到最左边的值。
C++代码:
直接使用层序遍历只需要记录最后一行第一个节点的数值就可以了
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
if(root==NULL) return 0;
queue<TreeNode*> que;
que.push(root);
int result=0;
while(!que.empty()){
int size=que.size();
for(int i=0;i<size;++i){
TreeNode* cur=que.front();
que.pop();
if(i==0) result=cur->val;
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
}
return result;
}
};