• 算法-二叉树


    ••••••••••••••••••••••••••••••••••••二叉树的核心思想:二叉树的子树也是一颗二叉树••••••••••••••••••••••••••••••••••••

    ••••••••••••••••••••••••••••••••••••二叉树的核心思想:二叉树的子树也是一颗二叉树••••••••••••••••••••••••••••••••••••

    ••••••••••••••••••••••••••••••••••••二叉树的核心思想:二叉树的子树也是一颗二叉树••••••••••••••••••••••••••••••••••••

    1.给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

    说明: 叶子节点是指没有子节点的节点。

    示例:
    给定如下二叉树,以及目标和 sum = 22,

                  5
                 /
                4   8
               /   /
              11  13  4
             /      /
            7    2  5   1

    返回:

    [
       [5,4,11,2],
       [5,8,4,5]
    ]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/path-sum-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    /**
     * 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 {
        int sum;
        vector<vector<int>> result;
        vector<int> v;
    public:
        vector<vector<int>> pathSum(TreeNode* root, int sum) {
            this->sum=sum;
            int s=0;  
            dfs(root,s);
            return result;
        }
        
        void dfs(TreeNode* node,int s){
            if(node==NULL) return;
            v.push_back(node->val);
            s+=node->val;
            if(s==sum && node->left==NULL && node->right==NULL){ 
                    result.push_back(v);                    
            } 
            dfs(node->left,s);       
            dfs(node->right,s);
            v.pop_back();//回溯
            s-=node->val;
            return;
        }
    };

    2.二叉树原地展开为链表

    给定一个二叉树,原地将它展开为链表。

    例如,给定二叉树

        1
       /
      2   5
     /   
    3   4   6

    将其展开为:

    1
     
      2
      
        3
        
          4
          
            5
            
              6

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    方法一:

    /**
     * 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 flatten(TreeNode* root) {
            TreeNode* last=root;
            preorder(root,last);
        }
        void preorder(TreeNode* root, TreeNode* &last){
            if(!root) return;
            if(!root->left && !root->right){
                last=root;
                return;
            }
            TreeNode* leftNode=root->left;
            TreeNode* rightNode=root->right;
            TreeNode* left_last=root;
            TreeNode* right_last=root;
            if(leftNode){
                preorder(root->left,left_last);
                root->right=leftNode;
                root->left=NULL;
                last=left_last;
            }
            if(rightNode){
                preorder(rightNode,right_last);
                last=right_last;
                left_last->right=rightNode;
            }
        }
    };

    典型的利用递归的思想,也是二叉树的核心思想。不去考虑整体,只考虑一颗子树。如何处理一颗子树?

    1)根节点左指针置空,右指针指向其左子树的第一个节点;

    2)将左子树与右子树相连,那么就需要获取左子树的左后一个节点的指针;

    3)该子树需要跟下一个节点相连,即获取该子树的最后一个节点的指针,也是右子树的最后一个节点的指针。

     总结下来,需要知道子树的最后一个节点的指针。设置last指针,利用前序遍历,将其赋值为最后一个节点。

    方法二:

    /**
     * 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 flatten(TreeNode* root){
            if(!root) return;
            flatten(root->left);
            flatten(root->right);
            TreeNode* temp_right=root->right;//临时指针保存右指针
            root->right=root->left;//右指针赋值前序
            root->left = NULL;//左指针置空
            while(root->right) root = root->right;//题目是前序遍历,对于一棵树,其前序遍历的最后一个节点就是最右的那个。这里找到左子树的最后一个结点指针
            root->right = temp_right;//左子树的最后一个节点的右指针指向根的右指针,将左右子树连接
    };

    a.采用后序遍历

    b.前序遍历的最后一个节点是最右的那个节点


     3.二叉树的右视图

    给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

    示例:

    输入: [1,2,3,null,5,null,4]
    输出: [1, 3, 4]
    解释:

       1            <---
     /  
    2     3         <---
         
      5     4       <---

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/binary-tree-right-side-view
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    /**
     * 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> rightSideView(TreeNode* root) {
            vector<int> res;
            if(root==nullptr) return res;
            queue<TreeNode*> q;
            q.push(root);
            while(!q.empty()){
               int size=q.size();
                while(size>0){
                    TreeNode* node=q.front();
                    q.pop();
                    if(node->left) q.push(node->left);
                    if(node->right) q.push(node->right);
                    size--;
                    if(size==0) res.push_back(node->val);
                }  
            }
            return res;
        }
    };
  • 相关阅读:
    VMware workstation中安装Ubuntu18.04server
    python一行命令安装chromedriver
    vim配置&相关问题
    博客园美化
    期望DP——HDU4035Maze
    [学习笔记]虚树
    线段树——51nod1593&CF515E 公园晨跑
    [STL] multiset
    [学习笔记] 线性基
    泛化物品优化树型DP——[HAOI2010]软件安装
  • 原文地址:https://www.cnblogs.com/chendaniu/p/11094209.html
Copyright © 2020-2023  润新知