zoukankan      html  css  js  c++  java
  • 算法复习:二叉树专题

    一、平衡二叉树

    leetcode 110. 平衡二叉树

    二叉树判断是否平衡。  对逐个结点判断左右子树是否满足条件。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int find_leaves(TreeNode* root,int floor,int max)
        {
            if(root==NULL)
                return max;
            if(root->left==NULL&&root->right==NULL)
            {
                if(max<floor)
                    max=floor;
                return max;
            }
            floor++;
            max=find_leaves(root->left,floor,max);
            max=find_leaves(root->right,floor,max);
            floor--;
            return max;
        }
    
        bool isBalanced(TreeNode* root) {
            if(root==NULL)
                return true;
            int left=find_leaves(root->left,0,0);
            if(root->left==NULL)
                left=-1;
            int right=find_leaves(root->right,0,0);
            if(root->right==NULL)
                right=-1;
            if(abs(left-right)>1)
                return false;
            bool a,b;
            a=isBalanced(root->left); 
            b=isBalanced(root->right);
            if(root->left==NULL&&root->right==NULL)
                return true;
            return (a&&b);
        }
    };
    leetcode 110

    二、二叉树层次遍历

    leetcode 513. 找树左下角的值

    层次遍历记录queue每次的队头

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        queue<TreeNode*>donser;
        int findBottomLeftValue(TreeNode* root) 
        {
            TreeNode* node;
            donser.push(root);
            int first=0;
            while(true)
            {
                int size=donser.size();
                if(size==0)
                    break;
                for(int i=0;i<size;i++)
                {
                    node=donser.front();
                    if(i==0)
                        first=node->val;
                    donser.pop();
                    if(node->left!=NULL)
                        donser.push(node->left);
                    if(node->right!=NULL)
                        donser.push(node->right);
                }
            }
            return first;
        }
    };
    leedcode 513

    三、二叉树先序遍历

    leetcode 114. 二叉树展开为链表

    实质上就是先序遍历,把每一个输出的节点存起来,最后连接起来就可以,不需要考虑链接规律。

    l/**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<TreeNode*> donser;
        void loop(TreeNode* root)
        {
            if(root==NULL)
                return;
            donser.push_back(root);
            loop(root->left);
            loop(root->right);
            return;
        }
        void flatten(TreeNode* root) //先序遍历
        {
            loop(root);
            if(donser.size()<=1)
                return;
            TreeNode* node;
            node=root;
            for(int i=1;i<donser.size();i++)
            {
                TreeNode* now;
                now=donser[i];
                node->left=NULL;
                node->right=now;
                node=now;
            }
            donser.clear();
            return;
        }
    };
    leetcode 114

     考虑不用辅助数组,就地转换。 node的右节点接在node的左节点的后面,再把node的左节点转移到右边,左边置null

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        void loop(TreeNode* root)
        {
            if(root==nullptr)
                return ;
            loop(root->left);
            loop(root->right);
            if(root->left!=nullptr)
            {
                TreeNode* tmp=root->left;
                while(tmp->right!=nullptr)
                    tmp=tmp->right;
                tmp->right=root->right;
            }
            else
                root->left=root->right;
            root->right=root->left;
            root->left=nullptr;
            return ;
        }
        void flatten(TreeNode* root) {
            TreeNode * tmp;
            TreeNode * tmp2;
            if(root==nullptr)
                return ;
            tmp=root->left;
            tmp2=root->right;
            loop(tmp);
            loop(tmp2);
            root->left=nullptr;
            root->right=tmp;
            if(tmp==nullptr)
            {
                root->right=tmp2;
                return;
            }
            while(tmp->right!=nullptr)
                tmp=tmp->right;
            tmp->right=tmp2;
        }
    };
    就地转换

    四、二叉树中序遍历

    leetcode 230. 二叉搜索树中第K小的元素

    对二叉搜索树来说,找第几小就是找中序遍历的第几个节点

    方法一:用辅助数组存节点值

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> donser;
        void loop(TreeNode* root,int k)
        {
            if(root->left!=NULL)
                loop(root->left,k);
            donser.push_back(root->val);
            if(root->right!=NULL)
                loop(root->right,k);
            return;
        }
        int kthSmallest(TreeNode* root, int k) 
        {
            loop(root,k);
            return donser[k-1];
        }
    };
    leetcode 230

    方法二:不用辅助数组,用两个全局变量

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int num=0,res=0;
        void loop(TreeNode* root,int k)
        {
            if(root==NULL)
                return;
            loop(root->left,k);
            num++;
            if(num==k)
            {
                res=root->val;
                return;
            }
            loop(root->right,k);
        }
        int kthSmallest(TreeNode* root, int k) 
        {
            loop(root,k);
            return res;
        }
    };/**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int num=0,res=0;
        void loop(TreeNode* root,int k)
        {
            if(root==NULL)
                return;
            loop(root->left,k);
            num++;
            if(num==k)
            {
                res=root->val;
                return;
            }
            loop(root->right,k);
        }
        int kthSmallest(TreeNode* root, int k) 
        {
            loop(root,k);
            return res;
        }
    };
    leetcode 230

    leetcode 94. 二叉树的中序遍历

     

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> donser;
        void loop(TreeNode* root)
        {
            if(root->left!=NULL)
                loop(root->left);
            donser.push_back(root->val);
            if(root->right!=NULL)
                loop(root->right);
            return;
        }
        vector<int> inorderTraversal(TreeNode* root) {
            if(root==NULL)
                return donser;
            loop(root);
            return donser;
        }
    };
    leedcode 94

     

     五、二叉树序列化

    leetcode 297. 二叉树的序列化与反序列化 or 面试题37. 序列化二叉树

    将string形式的树存储转化为Node形式,将Node形式转化为string形式,思想不难,实现起来有点复杂,涉及到string的处理,层序还原为树

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Codec {
    public:
    
        // Encodes a tree to a single string.
        string serialize(TreeNode* root) {
            queue<TreeNode*>donser;
            if(root==NULL)
                return "[]";
            donser.push(root);
            string outter="[";
            while(true)
            {
                int size=donser.size();
                if(size==0)
                    break;
                for(int i=0;i<size;i++)
                {
                    TreeNode* node;
                    node=donser.front();
                    donser.pop();
                    if(node==NULL)
                    {
                        outter=outter.insert(outter.size(),"null,");
                        continue;
                    }
                    else
                    {
                        outter=outter.insert(outter.size(),to_string(node->val)+",");
                    }
                    donser.push(node->left);
                    donser.push(node->right);
                }
            }
            outter[outter.size()-1]=']';
            while(outter[outter.size()-2]=='l')
            {
                outter.erase(outter.size()-6,5);
            }
            return outter;
        }
        TreeNode* make_node(queue<TreeNode*>donser)
        {
            if(!donser.size())
                return NULL;
            queue<TreeNode*>tmp;
            TreeNode* root=donser.front();
            TreeNode* node=root;
            tmp.push(donser.front());
            donser.pop();
            int lable=0;
            while(true)
            {
                int size=tmp.size();
                if(size==0)
                    break;
                while(size--)
                {
                    node=tmp.front();
                    tmp.pop();
                    if(node==NULL)
                        continue;
                    if(!donser.size())
                    {
                        lable=1;
                        break;
                    }
                    node->left=donser.front();
                    tmp.push(donser.front());
                    donser.pop();
                    if(!donser.size())
                    {
                        lable=1;
                        break;
                    }
                    node->right=donser.front();
                    tmp.push(donser.front());
                    donser.pop();
                }
                if(lable)
                    break;
            }
            return root;
        }
        // Decodes your encoded data to tree.
        TreeNode* deserialize(string data) {
            if(data=="[]")
                return NULL;
            data.erase(0,1);
            queue<TreeNode*>donser;
            while(data!="")
            {
                int num=0,lable=-1,lb=0;
                for(int i=0;;i++)
                {
                    if(data[0]=='n')
                    {
                        lable=-1;
                        break;
                    }
                    if(data[i]=='-')
                    {
                        lb=-2;
                        continue;
                    }
                    if(data[i]==','||data[i]==']')
                    {
                        lable=i;
                        break;
                    }
                    num*=10;
                    num+=data[i]-'0';
                }
                if(lable==-1)
                {
                    data.erase(0,5);
                    donser.push(NULL);
                }
                else
                {
                    if(lb==-2)
                    {
                        num*=-1;
                        lb=0;
                    }
                    data.erase(0,lable+1);
                    TreeNode* node=new TreeNode(num);
                    donser.push(node);
                }
            }
            TreeNode* root=donser.front();
            root=make_node(donser);
            return root;
        }
    };
    
    // Your Codec object will be instantiated and called as such:
    // Codec codec;
    // codec.deserialize(codec.serialize(root));
    leetcode 297

    六、由前序中序确定一颗二叉树

    leetcode 105. 从前序与中序遍历序列构造二叉树

     由两个序列划分左右子树,递归条件构建

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int str=0;
        TreeNode* loop(vector<int>& preorder,vector<int>& inorder)
        {
            vector<int>in_left,in_right;//先找中序的左右部分
            int lable=0;
            for(int i=0;i<inorder.size();i++)
            {
                if(inorder[i]==preorder[str])
                {
                    lable=1;
                    continue;
                }
                if(lable==0)
                    in_left.push_back(inorder[i]);
                if(lable==1)
                    in_right.push_back(inorder[i]);
            }
            
            TreeNode* node=new TreeNode(preorder[str]);
            if(in_left.size())
            {
                str++;
                node->left=loop(preorder,in_left);
            }
            if(in_right.size())
            {
                str++;
                node->right=loop(preorder,in_right);
            }
            return node;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            if(preorder.size()==0)
                return NULL;
            TreeNode* root;
            root=loop(preorder,inorder);
            return root;
        }
    };
    leetcode 105

     七、字典树—前缀树

    leetcode 208. 实现 Trie (前缀树)

     属于多叉树,重点关注这个,字节面试问过很多次

    struct TrieNode
    {
        TrieNode *next[26];
        bool is_end;
    };
    class Trie {
    public:
        /** Initialize your data structure here. */
        Trie() {}
        struct TrieNode * root=new TrieNode();
        void insert(string word) 
        {
            struct TrieNode * node=root;
            for(int i=0;i<word.size();i++)
            {
                if(node->next[word[i]-'a']==NULL)
                {
                    struct TrieNode * new_node=new TrieNode();
                    node->next[word[i]-'a']=new_node;
                }
                node=node->next[word[i]-'a'];
            }
            node->is_end=true;
        }
        bool search(string word) 
        {
            struct TrieNode * node=root;
            for(int i=0;i<word.size();i++)
            {
                if(node!=NULL)
                {
                    node=node->next[word[i]-'a'];
                }
            }
            if(node!=NULL&&node->is_end==true)
                return true;
            return false;
        }
        bool startsWith(string prefix) 
        {
            struct TrieNode * node=root;
            for(int i=0;i<prefix.size();i++)
            {
                if(node!=NULL)
                {
                    node=node->next[prefix[i]-'a'];
                }
            }
            if(node!=NULL)
                return true;
            return false;
        }    
    };
    
    /**
     * Your Trie object will be instantiated and called as such:
     * Trie* obj = new Trie();
     * obj->insert(word);
     * bool param_2 = obj->search(word);
     * bool param_3 = obj->startsWith(prefix);
     */
    leetcode 208

     

  • 相关阅读:
    [线段树][数学]JZOJ 4237 Melancholy
    [规律]JZOJ 4222 恐怖的奴隶主
    [Tarjan][基环树]JZOJ 4221 互相追逐的点
    [斯特林数][自然数幂和]JZOJ 4220 WYF的盒子
    奇妙的骚操作
    [树形DP][概率期望]JZOJ 4225 宝藏
    操作系统基础知识
    计算机硬件知识整理
    ORM的查询
    ORM的记录添加和删除
  • 原文地址:https://www.cnblogs.com/dzzy/p/12354574.html
Copyright © 2011-2022 走看看