写递归算法第一步是要明确递归函数的定义,不要跳入递归深陷其中,怎么理解呢比如说要计算二叉树节点的个数:明确int count(Treenode* root)函数:返回一个以root为根节点的树有多少个节点
int count(TreeNode* root) {
if (!root) return 0;
int left = count(root->left);
int right = count(root->right);
return left + right + 1;
}
class Solution {
public:
//明确函数的定义:返回 以root为根节点的左右子树交换之后的新的树,即镜像后的树
TreeNode* invertTree(TreeNode* root) {
if(!root) return root;
root->left=invertTree(root->left);//左子树已经镜像
root->right=invertTree(root->right);//右子树已经镜像
swap(root->left,root->right);//最后一步交换根节点的左右节点
return root;
}
};
class Solution {
public:
/*不能单纯的想到根节点相同时将左节点的next指向右节点,因为这忽略了根节点不同的情况
定义一个辅助数组help:将root1的next指向root2(即将每一层的节点连接起来)
*/
void help(Node* root1,Node* root2){
if(!root1||!root2) return;
help(root1->right,root2->left);
help(root1->left,root1->right);
help(root2->left,root2->right);
//以上已经把root1,root2下面的每一层节点连接起来了
//再把root1,root2连接起来
root1->next=root2;
}
Node* connect(Node* root) {
if(!root) return root;
help(root->left,root->right);
return root;
}
};
递归是一种非常重要的思想,二叉树的题基本都可用递归去解决,快排的思想我们回想一下,是不是采用了树的先序遍历
void quickSort(vector<int>&a,int L,int R){
if(L>R) return;
int mid=patition(a,L,R);
quickSort(a,L,mid-1);
qucikSort(a,mid+1,R);
}
回想一下归并排序,也有二叉树后序遍历的思想
void mergeSort(vector<int>&a,int L,int R){
if(L>R) return;
int mid=(L+R)/2;
mergeSort(a,L,mid);//先对a[L...mid]进行排序
mergeSort(a,mid+1,R);//再对a[mid+1,R]进行排序
//以上已经将两堆数组排好序,只差最后一步将两个数组合并起来
combine(a,L,mid,R)//最后将两个有序的数组合并起来
}
class Solution {
public:
/*要构建一个最大二叉树,每次得去找一个最大值,将它初始化为根节点,这里的思想和快排的思想相似,采用的是树的先序遍历
*/
TreeNode* help(vector<int>&a,int L,int R){
//递归退出条件
if(L>R) return nullptr;
int index=-1;//记录最大值的下标
int _max=INT_MIN;
//左闭右闭的区间
for(int i=L;i<=R;i++){
if(a[i]>_max){
_max=a[i];
index=i;
}
}
TreeNode* root=new TreeNode(_max);
//以上代码构造了最大根节点,现在需要的是将左右子树的最大根节点也构建出来
root->left=help(a,L,index-1);
root->right=help(a,index+1,R);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return help(nums,0,nums.size()-1);
}
};