Day17
110 平衡二叉树
使用递归反而好想一些,
先求高度,然后比较左右子树高度。当时没想明白怎么找到不满足就撤出递归。方法是在遍历后面加个判断,return-1,这样只要有一个循环return-1,就会一层层的全部退出。最后判断return的是不是-1就可以了。
class Solution {
public:
int getDepth(TreeNode* node){
if(node==NULL) return 0;
int left=getDepth(node->left);
if(left==-1) return -1;
int right=getDepth(node->right);
if(right==-1) return-1;
int result=0;
if(abs(left-right)>1){
result=-1;
}
else{
result= max(left,right)+1;
}
return result;
}
bool isBalanced(TreeNode* root) {
return getDepth(root)==-1?false:true;
}
};
迭代是写个getdepth函数,然后遍历所有节点,查询左右节点高度差,会重复遍历,效率不高。
257. 二叉树的所有路径
递归的写法:首先确定好遍历的逻辑关系,也就是递归本身,然后再根据递归之后的输入确定判断条件的具体写法。
本题有两种递归方法,其实本质都是保留一个字符串保存路径,一个容器result保存结果。
利用回溯的思想,当传入的参数没有&时,说明只是复制,递归本层退出后,参数不会跟着一起退出来。
class Solution {
public:
void travelsal(TreeNode* node,vector<int>& path,vector<string>& result){
path.push_back(node->val);
if(node->left==NULL&& node->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(node->left){
travelsal(node->left,path,result);
path.pop_back();
}
if(node->right){
travelsal(node->right,path,result);
path.pop_back();
}
return;
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
if(root==NULL) return result;
vector<int> path;
travelsal(root,path,result);
return result;
}
};
精简一下,也就是将path直接用string定义。
class Solution {
public:
void travelsal(TreeNode* node,string path,vector<string>& result){
path+=to_string(node->val);
if(node->left==NULL &&node->right==NULL){
result.push_back(path);
}
if(node->left){
path+="->";
travelsal(node->left,path,result);
path.pop_back();
path.pop_back();
}
if(node->right){
path+="->";
travelsal(node->right,path,result);
path.pop_back();
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
string path;
if(root== NULL){
return result;
}
travelsal(root,path,result);
return result;
}
};
迭代法:
使用前序,重点是使用两个栈,一个存遍历到的节点,一个对应的存储到这个节点的路径。
这里实在巧妙。
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
stack<TreeNode*> st;
stack<string> path;
if(root!=NULL){
st.push(root);
path.push(to_string(root->val));
}
while(!st.empty()){
TreeNode* node=st.top();
st.pop();
string spath=path.top();
path.pop();
if(node->left==NULL && node->right==NULL){
result.push_back(spath);
}
if(node->right){
path.push(spath+"->"+(to_string(node->right->val)));
st.push(node->right);
}
if(node->left){
path.push(spath+"->"+(to_string(node->left->val)));
st.push(node->left);
}
}
return result;
}
};
404.左叶子之和
本质也是遍历,递归法首先确定递归与终止条件,然后加上判断条件
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==NULL) return 0;
int leftval=sumOfLeftLeaves(root->left);
if(root->left!=NULL && root->left->left==NULL &&root->left->right==NULL){
leftval=root->left->val;
}
int rightval=sumOfLeftLeaves(root->right);
int sumval=leftval+rightval;
return sumval;
}
};
迭代法思路:本质就是遍历二叉树,然后查询所有节点的左节点,满足条件就加到sum中。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> st;
if(root!=NULL) st.push(root);
int sum=0;
while(!st.empty()){
TreeNode* node=st.top();
st.pop();
if(node->left && node->left->left==NULL && node->left->right==NULL){
sum+=node->left->val;
}
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
}
return sum;
}
};