一、654 最大二叉树
主要思路:
1)找到起始到结束区间段的最大值的index;
2)创建节点,初始化(这里需要结构体所有的entry都初始化),然后递归到子树;
3)注意区间是左闭右开,因此填入区间时候需要区分;
4)返回root节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* nums, int numsSize, int left, int right)
{
//函数返回接口
if(left >= right)
return NULL;
//找到最大值的index
int maxvalueidx = left;
for(int i = left + 1; i < right; i++)//遍历整个区间找到最大值
{
if(nums[i] > nums[maxvalueidx])
{
maxvalueidx = i;
}
}
//malloc一个节点
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = nums[maxvalueidx];
root->left = NULL;
root->right = NULL;
//递归调用
root->left = buildTree(nums, numsSize, left, maxvalueidx);//左区间 左闭右开原则
root->right = buildTree(nums, numsSize, maxvalueidx + 1, right);
return root;
}
struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize) {
if(numsSize == 0)
{
return NULL;
}
return buildTree(nums, numsSize, 0, numsSize);
}
二、617 合并二叉树
递归思路:
1)函数返回条件:如果root1为空,不管root2怎么样,直接返回root2;
2)把root1作为返回的节点,所以如果有值加到root1
3)root1的左右子树递归
struct TreeNode* mergeTrees(struct TreeNode* root1, struct TreeNode* root2) {
//利用前序中序后序遍历都可以
if(root1 == NULL) return root2;
if(!root2) return root1;
root1->val +=root2->val;
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
三、700 二叉搜索树中的搜索
1 首先理解二叉搜索树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
递归三要素:
1)返回条件:如果root为空,或者找到指定value;
2)单层递归:因为搜索树是有序的,所以应该判断;
3)因为不是全局搜索,找到指定条件需要返回,因此需要返回值。
struct TreeNode* searchBST(struct TreeNode* root, int val) {
if(root == NULL || root->val == val)
{
return root;
}
struct TreeNode* result = NULL;
if(root->val > val)
{
//在左子树
result = searchBST(root->left, val);
}
if(root->val < val)
{
result = searchBST(root->right, val);
}
return result;
}
四、98 验证二叉搜索树
这里遇到一个初始化问题:在leetcode上面,如果全局初始化,会导致数据异常!!!如下图,我把pre指针放在全局初始化,导致某一次预期pre应该为空,但是实际却没有。
struct TreeNode* pre;
bool check(struct TreeNode* root)
{
if(root == NULL)
return true;
bool left_flag = check(root->left);
//printf("L%d %d", left_flag, pre == NULL);
if(pre != NULL && pre->val >= root->val)
return false;
//printf("LL%d %d", left_flag, pre == NULL);
pre = root;
bool right_flag = check(root->right);
//printf("%d %d", left_flag, right_flag);
return left_flag && right_flag;
}
bool isValidBST(struct TreeNode* root) {
pre = NULL;
return check(root);
}
另外一种写法:
注意:maxvalue是在接口内部初始化的。
long long maxvalue;
bool check(struct TreeNode* root)
{
// if(pre && root && pre->val >= root->val)
// return false;
if(root == NULL)
return true;
bool left_flag = check(root->left);
printf("L %d \n", left_flag);
// if(pre && pre->val >= root->val)
// return false;
// if(pre)
// printf("LL%d %d %d\n", left_flag, pre->val, root->val);
// pre = root;
printf("right %lld %d\n", maxvalue, root->val);
if (maxvalue < root->val)
maxvalue = root->val;
else
return false;
printf("right\n");
bool right_flag = check(root->right);
printf("//%d %d\n", left_flag, right_flag);
return left_flag && right_flag;
}
bool isValidBST(struct TreeNode* root) {
//struct TreeNode* pre = NULL;
maxvalue = LONG_MIN;
return check(root);
}
迭代:
bool isValidBST(struct TreeNode* root) {
//pre = NULL;
//return check(root);
//迭代
//用来保存节点
struct TreeNode** NodeStk = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10001);
struct TreeNode* cur = root;
struct TreeNode* pre = NULL;
int top = -1;
while(cur || top > -1)
{
if(cur)
{
//前序遍历,一直入栈直到为空
NodeStk[++top] = cur;
cur = cur->left;
}
else
{
//cur为空,top就是叶子节点
cur = NodeStk[top];
top--;//出栈
if(pre && pre->val >= cur->val)//如果上一个节点的值超过当前的值
{
return false;
}
pre = cur;
cur = cur->right;//替换cur 遍历右节点 按照左中右的顺序
}
}
return true;
}