专题复习:二叉树(2)

剑指 Offer 27. 二叉树的镜像

方法一:利用辅助队列  以广度优先的顺序将 节点依次存入辅助队列中

class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(!root) return NULL;
        queue<TreeNode*> a;
        a.push(root);
        while(!a.empty())
        {
            TreeNode *temp = a.front();
            a.pop();
            
            TreeNode *t = temp->left;
            temp->left = temp->right;
            temp->right = t;

            if(temp->left) a.push(temp->left);
            if(temp->right) a.push(temp->right);
        }
        return root;

    }
};

方法二:利用递归

递归函数需要具备的条件:(1)结束条件 (2)调用自身 (3)返回值  

class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(!root) return root;
        TreeNode *temp = root->left;
        root->left = root->right;
        root->right = temp;
        mirrorTree(root->left);
        mirrorTree(root->right);
        return root;

    }
};

剑指 Offer 26. 树的子结构

思路:利用递归

首先需要函数 判断以a为根的子树 与以b为根的子树 是否一致的函数 judge

如果以a为根的子树 与以b为根的子树不一致,那么看以a->left为根的子树 与以b为根的子树 是否一致 和以a->right为根的子树 与以b为根的子树 是否一致

class Solution {
    //判断以a为根的子树 与以b为根的子树 是否一致
    bool judge(TreeNode *a, TreeNode *b)
    {
        if(!b) return true;
        if(!a || a->val != b->val) return false;
        return judge(a->left, b->left)&&judge(a->right, b->right);
    }
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(!A || !B) return false;
        if(judge(A, B)) return true;
        return isSubStructure(A->left, B)|| isSubStructure(A->right, B);
    }
};

leetcode98 98. 验证二叉搜索树

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

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

递归函数:的入参要包含当前子树的 数值范围 

class Solution {

    bool isSearchTree(TreeNode *root, long minVal, long maxVal)
    {
        if(!root) return true;
        if(root->val <= minVal || root->val >= maxVal) return false;
        return isSearchTree(root->left, minVal, root->val) && isSearchTree(root->right, root->val, maxVal);
    }
public:
    bool isValidBST(TreeNode* root) {
        return isSearchTree(root, LONG_MIN, LONG_MAX);
    }
};

leetcode450. 删除二叉搜索树中的节点

思路:由于二叉搜索树是满足左子树的值均小于根节点的值 ,右子树的值均大于根节点的值,利用递归

class Solution {
    TreeNode* findMinNode(TreeNode* root) //找到以root为根节点的最小值
    {
        while(root->left)
        {
            root = root->left;
        }
        return root;
    }

public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(!root) return root;
        if(key < root->val) //key在root的左子树中
        {
            root->left = deleteNode(root->left, key);
        }
        else if(key > root->val)//key在root的右子树中
        {
            root->right = deleteNode(root->right, key);
        }
        else//root->val == key 此时要做删除节点操作
        {
            //左子树为空 或者右子树为空 或者左右子树均为空
            if(!root->left) return root->right;
            if(!root->right) return root->left;
            //左右子树均不为空 首先找到右子树中的最小值,然后将root->val替换为该值 然后删除右子树中的最小值
            TreeNode * temp = findMinNode(root->right);
            root->val = temp->val;
            root->right = deleteNode(root->right, root->val);
        }
        return root;


    }
};

leetcode103. 二叉树的锯齿形层序遍历

思路:利用辅助队列,只不过需要对临时数组进行逆序操作

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if(!root) return res;
        queue<TreeNode*> a;
        a.push(root);
        int line = 0;
        while(!a.empty())
        {
            int size = a.size();
            vector<int> tmp;
            while(size--)
            {
                TreeNode *temp = a.front();
                a.pop();
                tmp.push_back(temp->val);
                if(temp->left) a.push(temp->left);
                if(temp->right) a.push(temp->right);
            }
            if(line%2 == 1)
            {
                reverse(tmp.begin(), tmp.end());
            }
            line++;
            res.push_back(tmp);
        }
        return res;

    }
};

剑指 Offer 34. 二叉树中和为某一值的路径

思路:利用递归  

注意:该路径要既包含root还要包含叶节点  对于树 [1, 2] 如果target为1 虽然 1== 树的root但是,该路径不包含叶节点,所以也返回false

class Solution {
    vector<vector<int>> res;
public:
    void dfs(TreeNode *root, int target, vector<int>& temp)
    {
        if(!root) return;
        if(target == root->val && !root->left && !root->right) //说明已经找到该路径
        {
            temp.push_back(root->val); //注意 在临时数组中push一次 就要进行pop
            res.push_back(temp);
            temp.pop_back();
        }
        else
        {
            temp.push_back(root->val);
            if(root->left) dfs(root->left, target - root->val, temp);
            if(root->right) dfs(root->right, target - root->val, temp);
            temp.pop_back();
        }
    }  
    vector<vector<int>> pathSum(TreeNode* root, int target) {
    if(!root) return {};
    vector<int> temp;
    dfs(root, target, temp);
    return res;
    }
};

剑指 Offer 55 - I. 二叉树的深度

思路:利用递归 求左子树和右子树的高度 

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root) return 0;
        int leftHight = maxDepth(root->left);
        int rightHight = maxDepth(root->right);
        return max(leftHight, rightHight) + 1;
    }
};

leetcode111:二叉树最小高度

思路:利用递归,但需要注意的是:比如,当root->left为空,但是root->right不为空时,二叉树的最小高度不能为1,因为在二叉树的最小高度时,要包含至少一个叶节点

class Solution {
public:
    int minDepth(TreeNode* root) {
        if(!root) return 0;
        if(!root->left && !root->right) //左右子树都为空 
        {
            return 1;
        }
        else if(!root->left && root->right)//左子树为空 右子树不为空
        {
            int right = minDepth(root->right);
            return right + 1;
        }
        else if(root->left && !root->right)//右子树为空 左子树不为空
        {
            int left = minDepth(root->left);
            return left+1;
        }
        else     //左右子树均不为空
        {
            int left = minDepth(root->left);
            int right = minDepth(root->right);
            return min(left, right) + 1;
        }
    }
};

Retinex算法是图像处理领域中一种模拟人眼视觉特性的经典算法,其名称来源于“Retina”(视网膜)和“NeXt”(下一步),旨在通过模拟人眼对光线的处理过程,增强图像的局部对比度,改善图像质量,使色彩更加鲜明,同时降低光照变化的影响。该理论由Gibson在1950年提出,基于两个核心假设:一是图像的颜色信息主要体现在局部亮度差异而非全局亮度;二是人眼对亮度对比更敏感,而非绝对亮度。 Retinex算法的核心思想是通过增强图像的局部对比度来改善视觉效果。它通过计算图像的对数变换并进行局部平均,从而突出图像的细节和色彩,同时减少光照不均匀带来的影响。 MSR是Retinex算法的一种改进版本,引入了多尺度处理的概念。它通过以下步骤实现: 图像预处理:对原始图像进行归一化或滤波,以减少噪声和光照不均匀的影响。 多尺度处理:使用不同大小的高斯核生成多个尺度的图像,每个尺度对应不同范围的特征。 Retinex处理:在每个尺度上应用Retinex算法,通过计算对数变换和局部平均来增强图像细节。 融合:将不同尺度的处理结果通过权重融合,生成最终的增强图像。MSR能够更好地捕捉不同大小的细节,并降低噪声的影响。 MSSR是MSR的变种,它不仅在尺度上进行处理,还考虑了空间域上相邻像素之间的关系。这种处理方式有助于保留图像的边缘信息,同时提高图像的平滑性,进一步提升图像质量。 在提供的压缩包中,包含三个MATLAB文件:SSR.m、MSRCR.m和MSR.m。这些文件分别实现了不同版本的Retinex算法: SSR.m:实现单一尺度的Retinex算法,仅在固定尺度上处理图像。 MSRCR.m:实现改进的减法Retinex算法,通过颜色恢复步骤纠正光照变化对颜色的影响。 MSR.m:实现基础的多尺度Retinex算法,涉及多尺度图像处理和Retinex操作。 MATLAB是一种广泛应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值