传统弱校HFUT的蒟蒻,真相只有一个

算法复习:二叉树专题

一、平衡二叉树

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

 

 

 

 

 

posted @ 2020-02-23 21:52  未名亚柳  阅读(204)  评论(0编辑  收藏  举报