• 10.二叉树


    二叉树
    作为单链表的升级版,我们通常接触的树都是二叉树(binary tree),即每个节点最多有两个子节点;
    可以看出,其与链表的主要差别就是多了一个子节点的指针。
    struct TreeNode{
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x):val(x),left(NULL),right(NULL) {}
    };
    104.求一个二叉树的最大深度;
    Input:
                3
            9       20
                   15  7
    Output:3 
    
    int maxDepth(TreeNode* root){
        if(!root) return 0;
        int l=1+maxDepth(root->left);
        int r=1+maxDepth(root->right);
        return l>r ? l:r;
    }
    
    
    
    110.平衡二叉树
    题目:判断一个二叉树是否平衡。树平衡的定义是,对于树上的任意节点,其两侧节点的最大深度差值不得大于1
    题解:解法类似于求树的最大深度,但有两个不同的地方:一是我们需要先处理树的深度再进行比较,二是如果我们在处理子树时发现其已经不平衡了,
    则可以返回一个-1,使得所有其长辈节点可以避免多余的判断(本题的判断比较简单,做差后取绝对值即可;但如果此处是一个开销较大的比较过程,
    则避免重复判断可以节省大量的计算时间)。
    
    bool isBalanced(TreeNode* root){        //主函数
        return helper(root) != -1;
    }
    
    int helper(TreeNode* root){
        if(!root){
            return 0;
        }
        int left = helper(root->left);     //递归
        int right = helper(root->right);    //递归
        if(left == -1 || right == -1 || abs(left - right) > 1){     //abs取绝对值函数是重点
            return -1;
        }
        return 1+max(left, right);
    }
    
    
    101.对称二叉树
    题目描述:判断一个二叉树是否对称
    输入输出:输入是一个二叉树,输出一个布尔值,表示该树是否对称
    Input:
                        1
                    2       2
                   3 4     4 3
    Output:true
    题解:判断一个树是否对称等价于判断左右子树是否对称,笔者一般习惯将判断两个子树是否相等或对称的题的解法叫做“四步法”:
    1.如果两个子树都为空指针,则它们相等或对称
    2.如果两个子树只有一个为空指针,则它们不相等或不对称
    3.如果两个子树根节点的值不相等,则它们不相等或不对称
    4.根据相等或对称要求,进行递归处理
    
    //主函数
    bool isSymmetric(TreeNode *root){
        return root? isSymmetric(root->left, root->right):true;
    }
    //辅函数
    bool isSymmetric(TreeNode* left, TreeNode* right){
        if(!left && !right){
            return true;
        }
        if(!left || !right){
            return false;
        }
        if(left->val != right->val){
            return false;
        }
        return isSymmetric(left->left, right->right) && isSymmetric(left->right, right->left);      //false && false 为 false
    }
    
    
    
    637.二叉树的层平均值
    题目描述:给定一个二叉树,求每一层的节点值的平均数。
    输入输出样例:
    输入是一个二叉树,输出是一个一位数组,表示每层节点值的平局数。
    Input:
                        3
                    9       20
                          15   7
    Output:[3,14.5,11]
    题解:利用广度优先搜索(一般用queue结构处理 empty()、push()、pop()、front()函数),我们可以很方便的求取每层的平均值。
    queue 先进先出
    vector<double> averageOfLevels(TreeNode* root){
        vector<double> ans;         //返回值
        if(!root){                  //异常判断
            return ans;
        }
        queue<TreeNode*> q;         //定义队列
        q.push(root);
        while (!q.empty()){
            int count = q.size();       //count结合queue先进先出
            double sum=0;
            for(int i=0; i<count; ++i){
                TreeNode* node = q.front();     //取值
                q.pop();                        //pop
                sum += node->val;               //累加
                if(node->left){                 //左子树
                    q.push(node->left);
                }
                if(node->right){                //右子树
                    q.push(node->right);
                }
            }
            ans.push_back(sum/count);
        }
        return ans;
    }
    
    
    
    144.二叉树的前序遍历
    题目描述:不使用递归,实现二叉树的前序遍历。
    输入输出样例:输入一个二叉树,输出一个数组,为二叉树前序遍历的结果
    Input:  
                1
                    2
                   3
    Output:[1,2,3]
    题解:因为递归的本质是栈调用,因此我们可以通过栈来实现前序遍历。注意入栈的顺序。
    栈:可以想象成一个“羽毛球筒”或“子弹夹”,后进先出
    栈数据结构名为stack top()、push()、pop()、empty()
    前中后序遍历,指的是root节点的位置;子节点先左后右
    vector<int> preorderTraversal(TreeNode* root){
        vector<int> ret;
        if(!root){
            return ret;
        }
        stack<TreeNode*> s;
        s.push(root);
        while(!s.empty()){
            TreeNode* node = s.top();
            s.pop();
            ret.push_back(node->val);
            if(node->right){
                s.push(node->right);        //先右后左,保证左子树先遍历
            }
            if(node->left){
                s.push(node->left);
            }
        }
        return ret;
    }
     


     类型
    1. 贪心算法
    2. 双指针 
    3. 二分查找    
    4. 排序算法    
    5. 二维数组的搜索
    6. 动态规划 
    7. 数据结构-stl 
    8. 字符串比较、匹配 
    9. 链表
    10. 二叉树
     
  • 相关阅读:
    jquery ajax 返回数据时 ff正常,ie接受到数据但是显示不了
    查看IIS日志并且分析其中的错误日志
    用eventvwr查看系统日志
    C++实现Trie 树
    [算法之美笔记02] 栈模拟网页的前进后退 ; 阻塞队列与并发队列
    MySQL学习小记(三) 结合JDBC实现用户的登录响应
    [算法之美笔记01] 数组,链表的删除和垃圾回收,缓存机制有什么关系
    [埋坑系列] 基于QT/C++的杰瑞走迷宫小游戏 :1.大体构造
    品味C++实现AVL树的删除操作
    C++实现AVL树的四种旋转
  • 原文地址:https://www.cnblogs.com/go-ahead-wsg/p/14594489.html
Copyright © 2020-2023  润新知