【刷题笔记18 二叉树 part05】

二叉树的遍历

找树左下角的值

513.找树左下角的值

法1:层序遍历

		int findBottomLeftValue(TreeNode* root) {
        //递归
        //迭代 层序遍历
        queue<TreeNode*>que;
        if (root != NULL) que.push(root);
        int ans;
        while (!que.empty()){
            int size = que.size();
            for (int i = 0; i < size; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                //记录该层最左侧元素
                if (i == 0)ans = cur->val;
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }
        }
        return ans;
    }

法2:递归

int ans = 0, maxDepth = INT_MIN;
    void travesal(TreeNode* root, int depth){
        //递归 + 回溯
        if(root->left == NULL && root->right ==NULL){
            if (depth > maxDepth) {
                maxDepth = depth;
                ans = root->val;
            }
            return;
        }
        /**
         * 确定单层递归的逻辑
            在找最大深度的时候,递归的过程中\
            依然要使用回溯,代码如下:
         */
        if (root->left){
            depth++;
            travesal(root->left,depth);
            depth--;
        }
        if (root->right){
            depth++;
            travesal(root->right,depth);
            depth--;
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        travesal(root,0);
        return ans;
    }

路径总和

112. 路径总和
法1: 递归

   
bool hasPathSum(TreeNode* root, int targetSum) {
        if (!root) return false;
        if (!root->left && !root->right && targetSum == root->val)return true;
        return hasPathSum(root->left,targetSum - root->val) || hasPathSum(root->right,targetSum - root->val);
    }

法2:迭代

 bool hasPathSum(TreeNode* root, int targetSum){
//        迭代
    if(!root) return false;
    // 此时栈里要放的是pair<节点指针,路径数值>
    stack<pair<TreeNode*,int>>st;
    st.push(pair<TreeNode*,int>(root,root->val));
    while(!st.empty()){
        pair<TreeNode*,int> node = st.top();
        TreeNode* cur = node.first;
        st.pop();
        if (!cur->left && !cur->right && targetSum == node.second){
            return true;
        }
        if (cur->left)
            st.push(pair<TreeNode*,int>(cur->left,node.second + cur->left->val));
        if (cur->right)
            st.push(pair<TreeNode*,int>(cur->right,node.second + cur->right->val));
    }
        return false;
}

路径总和ii

113.路径总和ii

法1:递归

    vector<vector<int>> ans;
    vector<int>path;
    void traversal(TreeNode* root,int count){
        if (!root->left && !root->right && count == 0) {
            ans.push_back(path);
            return;
        }
        if (!root->left && !root->right)
            return;
        if (root->left) {
            path.push_back(root->left->val);
            count -= root->left->val;
            traversal(root->left, count);
            count += root->left->val;
            path.pop_back();
        }
        if (root->right) {
            path.push_back(root->right->val);
            count -= root->right->val;
            traversal(root->right, count);
            count += root->right->val;
            path.pop_back();
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        path.clear();
        ans.clear();
        if (!root) return ans;
        path.push_back(root->val);
        traversal(root,targetSum - root->val);
        return ans;
    }

从中序与后序遍历序列构造二叉树

106.从中序与后序遍历序列构造二叉树

法1:递归

     TreeNode* traversal(vector<int>& inOrder, vector<int>& postOrder){
        if (postOrder.size() == 0)return NULL;
        //找切割点
        int deli = postOrder.back();
        //构造二叉树根节点
        TreeNode* ans = new TreeNode(deli);
        if (postOrder.size() == 1) return ans;
        int delimiter;
        for (int i = 0; i < inOrder.size(); ++i) {
            if (inOrder[i] == deli)
                delimiter = i;
        }
        //切割中序数组
        vector<int> inLeftOrder(inOrder.begin(),inOrder.begin() + delimiter);
        vector<int> inRightOrder(inOrder.begin() + delimiter + 1,inOrder.end());
        //收缩数组
        postOrder.resize(postOrder.size() - 1);
        //切割后序数组
        vector<int> postLeftOrder(postOrder.begin(),postOrder.begin() + inLeftOrder.size());
        vector<int> postRightOrder(postOrder.begin() + inLeftOrder.size(),postOrder.end());
        //递归
        ans->left = traversal(inLeftOrder, postLeftOrder);
        ans->right = traversal(inRightOrder, postRightOrder);
        return ans;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (postorder.size() == 0 || inorder.size() == 0 )return NULL;
        return traversal(inorder,postorder);
    }

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

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

法1:递归

     TreeNode* traversal(vector<int>&inorder,int inorderBegin,int inorderEnd,vector<int> preorder,int preorderBegin,int preorderEnd){
        if (preorderBegin == preorderEnd) return NULL;
        int rootValue = preorder[preorderBegin];
        TreeNode* root = new TreeNode(rootValue);

        if (preorderEnd - preorderBegin == 1) return root;//因为左闭右开,说明数组中只有一个元素
        int delimiter;
        for (delimiter = inorderBegin; delimiter < inorderEnd; ++delimiter) {//inorderBegin;
            if (inorder[delimiter] == rootValue) break;
        }

        int leftInorderBegin = inorderBegin;
        int leftInorderEnd =  delimiter;
        int rightInorderBegin = delimiter + 1;
        int rightInorderEnd = inorderEnd;


        int leftPreorderBegin = preorderBegin + 1;
        int leftPreorderEnd = preorderBegin + 1 + delimiter - leftInorderBegin;//区间长度
        int rightPreorderBegin = preorderBegin + 1 + delimiter - leftInorderBegin;
        int rightPreorderEnd = preorderEnd;

        root->left = traversal(inorder,  leftInorderBegin, leftInorderEnd,  preorder, leftPreorderBegin, leftPreorderEnd);
        root->right = traversal(inorder, rightInorderBegin, rightInorderEnd,  preorder, rightPreorderBegin, rightPreorderEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder.size() == 0 || inorder.size() == 0)return NULL;
        return traversal(inorder,0,inorder.size(),preorder,0,preorder.size());

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值