20210330:二叉树力扣相关习题复习(上)

20210330:二叉树力扣相关习题复习(上)

题目

    1. 路径总和 II
      在这里插入图片描述
    1. 二叉树的最近公共祖先
      在这里插入图片描述
    1. 二叉树展开为链表
      在这里插入图片描述

思路与算法

    1. 路径总和 II:经典三序遍历二叉树题目,需要保存路径,熟悉流程
    1. 二叉树的最近公共祖先:变相的求路径的题目,巩固遍历的技巧,最后只需要从短的路径头开始同步遍历即可,相同的路径会不断覆盖res直至最近公共祖先节点。
    1. 二叉树展开为链表:时间原因,投机取巧使用了vector保存前序遍历的路径,再进行相邻节点的连接即可完成链表。

代码实现

    1. 路径总和 II
      java版本:从给定的target中做减法
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    

    public List<List<Integer>> pathSum(TreeNode root, int sum) {
    
    

        // 新建结果集
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
    
    
            return res;
        }

        // 双端队列来存放对应的路径数组
        Deque<Integer> path = new ArrayDeque<>();
        pathSum(root, sum, path, res);
        return res;
    }

    public void pathSum(TreeNode node, int sum, Deque<Integer> path, List<List<Integer>> res) {
    
    

        // 递归终止条件
        if (node == null) {
    
    
            return;
        }

        // 从当前sum中减去当前节点的值,再将减去的这个节点值添加到path队列存放
        sum -= node.val;
        path.addLast(node.val);
        
        if (sum == 0 && node.left == null && node.right == null) {
    
    
            // path 全局只有一份,必须做拷贝
            res.add(new ArrayList<>(path));
            // 注意:这里 return 之前必须重置
            path.removeLast();
            return;
        }

        pathSum(node.left, sum, path, res);
        pathSum(node.right, sum, path, res);
        // 递归完成以后,必须重置变量
        path.removeLast();
    }
}

cpp版本:从0开始计算path和

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
    
    
        vector<vector<int>> res;
        vector<int> path;
        int path_value = 0;
        preOrder(root,path_value,targetSum,path,res);
        return res;
    }
public:
    void preOrder (TreeNode* node,int &path_value,int targetSum,vector<int> &path,vector<vector<int>> &res) {
    
    
        if (!node) {
    
    
            return;
        }
        path_value += node->val;
        path.push_back(node->val);
        if (!node->left && !node->right && path_value == targetSum) {
    
    
            res.push_back(path);
        }
        preOrder(node->left,path_value,targetSum,path,res);
        preOrder(node->right,path_value,targetSum,path,res);
        path_value -= node->val;
        path.pop_back();
    }
};
    1. 二叉树的最近公共祖先
/**
 * 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:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        vector<TreeNode*> path;
        vector<TreeNode*> p_path;
        vector<TreeNode*> q_path;
        int flag = 0;
        preOrder(root,p,path,p_path,flag);
        path.clear();
        flag = 0;
        preOrder(root,q,path,q_path,flag);
        int path_len = 0;
        if (p_path.size() < q_path.size()) {
    
    
            path_len = p_path.size();
        } else {
    
    
            path_len = q_path.size();
        }
        TreeNode* res = NULL;
        for (int i = 0; i < path_len; ++i) {
    
    
            if (p_path[i] == q_path[i]) {
    
    
                res = p_path[i];
            }
        }
        return res;
    }   

private:
    // 尽量不使用全局变量
    void preOrder(TreeNode* node,TreeNode* search,vector<TreeNode*> &path,vector<TreeNode*> &res,int &flag){
    
    
        if (!node || flag == 1) {
    
    
            return;
        }
        path.push_back(node);
        if (node == search) {
    
    
            flag = 1;
            res = path;
        }
        preOrder(node->left,search,path,res,flag);
        preOrder(node->right,search,path,res,flag);
        path.pop_back();
    }
};
    1. 二叉树展开为链表
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void flatten(TreeNode* root) {
    
    
        vector<TreeNode*> node_vec;
        preOrder(root,node_vec);
        for (int i = 1;i < node_vec.size(); ++i) {
    
    
            node_vec[i - 1]->left = NULL;
            node_vec[i - 1]->right = node_vec[i];
        }
    }
private:
    void preOrder (TreeNode* node,vector<TreeNode*> &node_vec) {
    
    
        if (!node) 
            return;
        node_vec.push_back(node);
        preOrder(node->left,node_vec);
        preOrder(node->right,node_vec);
    }
};

写在最后

  1. 三月最后一天了,本月状态很一般,继续调整状态,忙起来就好了。

猜你喜欢

转载自blog.csdn.net/qq_36828395/article/details/115339361