代码随想录算法训练营day17-leetcode-二叉树05: 113.路径综合2,654.最大二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树

 113.路径综合2(多理解理解)

int** ret;
int retSize;
int* retColSize;

int* path;
int pathSize;

void dfs(struct TreeNode* root, int targetSum) {
    if (root == NULL) {
        return;
    }
    path[pathSize++] = root->val;//加入预备输出的路径
    targetSum -= root->val;

    if (root->left == NULL && root->right == NULL && targetSum == 0) {
        //到叶子结点,且targetsum刚好降为0,符合题意,输出路径!
        int* tmp = malloc(sizeof(int) * pathSize);
        memcpy(tmp, path, sizeof(int) * pathSize);
        ret[retSize] = tmp;
        retColSize[retSize++] = pathSize;
    }

    dfs(root->left, targetSum);
    dfs(root->right, targetSum);
    pathSize--;//表示回退了,也就是找完left 和 right都没有符合题意的情况,所以回退到上一个结点
}

int** pathSum(struct TreeNode* root, int targetSum, int* returnSize, int** returnColumnSizes) {
    ret = malloc(sizeof(int*) * 2001);
    retColSize = malloc(sizeof(int) * 2001);
    path = malloc(sizeof(int) * 2001);
    retSize = pathSize = 0;

    dfs(root, targetSum);
    
    *returnColumnSizes = retColSize;
    *returnSize = retSize;
    return ret;
}

654.最大二叉树

力扣题目地址(opens new window)

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

注意**:

用指针遍历数组(char*,int*)

int*p=nums;此时*p是int,指向nums[0]

for(int *p=nums;p< nums+size;p++) 用int*+x,表示指针向右移动x步

int findmax(int* nums, int numsSize){//返回第几位是最大值
    int maxnumber=INT_MIN;
    int *maxp=nums;

    int *p=nums;
    
    for(p=nums;p<nums+numsSize;p++){
        if(*p>maxnumber){
            maxnumber=*p;
            maxp=p;
        }
    }
    
    return (maxp-nums);
}

struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize) {
    if (nums==NULL) return NULL;
    if(numsSize<=0) return NULL;
    

    struct TreeNode* b=(struct TreeNode* )malloc(sizeof(struct TreeNode));
    int i=findmax(nums, numsSize);
    b->val=nums[i];
    
    b->left=constructMaximumBinaryTree(nums,i);
    b->right=constructMaximumBinaryTree(nums+i+1,numsSize-i-1);
    return b;
}

617.合并二叉树

力扣题目链接(opens new window)

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

struct TreeNode* mergeTrees(struct TreeNode* root1, struct TreeNode* root2) {
    if(root1==NULL && root2==NULL) return NULL;

    //有一个是空的
    if(root1!=NULL && root2==NULL) return root1;
    else if(root1==NULL && root2!=NULL) return root2;
    
    
    root1->val=root2->val+root1->val;//都不是空的,需要合并
    root1->left=mergeTrees(root1->left,root2->left);
    root1->right=mergeTrees(root1->right,root2->right);

    return root1;
}

700.二叉搜索树中的搜索

力扣题目地址(opens new window)

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

二叉搜索树:

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树
struct TreeNode* searchBST(struct TreeNode* root, int val) {
    if(root==NULL) return NULL;

    int x=root->val;
    if(x==val) return root;
    if(x>val) return searchBST(root->left,val);
    else return searchBST(root->right,val);

}

98.验证二叉搜索树

力扣题目链接(opens new window)

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

注意:

二叉搜索树的性质:

不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。

我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。所以以上代码的判断逻辑是错误的。

1、用最大值、最小值来判断

int isBSTUtil(struct TreeNode* node, long long min, long long max)  
{  
  /* 是一颗空树 */
  if (node==NULL)  
     return 1; 
        
  /* 结点的值小于等于最小值,或者大于等于最大值都是不合理的,返回false */  
  if (node->val <= min || node->val >= max)  
     return 0;  
  
  /*否则递归地判断结点的左子树和右子树*/
  return 
    isBSTUtil(node->left, min, node->val) && 
    isBSTUtil(node->right, node->val, max); 
}  

2、中序遍历 

要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。

有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值