算法-二叉树

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

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

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

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;
    }
};

 

posted @ 2019-06-26 22:07  COOHAHAHA  阅读(158)  评论(0编辑  收藏  举报