Day 18 | 513.找树左下角的值 & 112.路径总和 & 106.从中序与后序遍历构造二叉树

        emm..突如其来的疫情让图书馆被封,我的电脑ipad全不在身边。。说是封三天于是本来打算美美躺三天然后拿到电脑再补。结果三天又三天,所以我只好借舍友电脑补裤裆呜呜呜。很不习惯,但是幸好只用浏览器就可以完成任务!希望让我早日回到图书馆!

        其实这三道题,我只能算是看懂了,自己写完全写不出来。第二道题说是变量隐含了回溯但是我看不出来。。对递归的理解还需加强。

513.找树左下角的值

        本道题首先要知道什么是左下角的值:是最大深度的最左边的叶子节点。

        因此首先要寻找最大深度的节点,每深入一层,deep++后要回溯deep-1以更新深度值。找到最大深度后,因为是先遍历左子树再遍历右子树,因此遍历到左子树时返回即可。

递归回溯求最大深度:

①定义全局变量最大深度maxdeep以及value。

②递归三要素: 

        参数:根节点&deep(当前深度),返回值:void

        终止条件:当该节点为叶子节点且为最大深度时,更新value值为当前节点val值。

        单层递归条件:先递归左子树,当左子树不为空时deep+1,递归调用该函数,调用完毕回溯deep++。 然后递归同理右子树。

③返回最左子树的value值。

class Solution {
    int maxdeep=-1;
    int value;
    public int findBottomLeftValue(TreeNode root) {
        value=root.val;
        findLeftValue(root,0);
        return value;
    }
     private void findLeftValue (TreeNode root,int deep) {
        if(root.left==null&&root.right==null){
             if(deep>maxdeep){
                 maxdeep=deep;
                 value=root.val;
        }
             return;
        }
        if(root.left!=null){
                 deep++;
                 findLeftValue(root.left,deep);
                 deep--;
             }
        if(root.right!=null){
                 deep++;
                 findLeftValue(root.right,deep);
                 deep--;
        }
     }
}

112.路径总和

 

递归减法求路径总和:

递归三要素:

①参数:root节点,sum值作为参数。返回值boolean

②终止条件:当当前节点为叶子节点且sum值减为0时返回true。

③单层递归条件:每次调用该函数,将左/右子树作为参数传递。若递归函数返回true,则该函数继续返回true。否则,遍历完毕没有符合条件的路径,返回false。

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null){return false;}
        targetSum-=root.val;
        if(root.left==null&&root.right==null&&targetSum==0){return true;}
        if(root.left==null&&root.right==null&&targetSum!=0){return false;}

        if(root.left!=null){
            boolean left=hasPathSum(root.left,targetSum);
            if(left){return true;}
        }
        if(root.right!=null){
            boolean right=hasPathSum(root.right,targetSum);
            if(right){return true;}
        }
        return false;
    }
}

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

递归解法:

        map存储中序遍历数组的节点值和下标,递归调用find函数求出各个节点关系。

find函数递归三要素:

①参数:中序数组,前序数组的开始下标,结束下标,后序数组,后序数组的开始下标,结束(下标统一为前开后闭),返回值:root结点。

②终止条件:当开始下标大于等于结束下标时终止。

③单层递归:首先确定根节点。后序遍历的最后一个元素即为根节点,确定其在中序的下标。创root结点,值即为根节点的value值。中序数组中根节点左侧为左子树,右侧为右子树。在后序数组中,左子树的数量lenofLeft和中序数组同。则前lenofLeft即为左子树,lenofLeft+1至postorder-1为右子树(减1为减去了根节点)。得出根节点的左右孩子。最后返回该节点即可。

 

class Solution {
    Map<Integer, Integer> map; 
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return findNode(inorder,  0, inorder.length, postorder,0, postorder.length);  
    }
    
    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        if (inBegin >= inEnd || postBegin >= postEnd) {  
            return null;
        }
        int rootIndex=map.get(postorder[postEnd-1]);
        TreeNode root=new TreeNode(inorder[rootIndex]);
        int lenofLeft=rootIndex-inBegin;
        root.left=findNode(inorder,inBegin,rootIndex,postorder,postBegin,postBegin+lenofLeft);
        root.right=findNode(inorder,rootIndex+1,inEnd,postorder,postBegin+lenofLeft,postEnd-1);
        return root;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建二叉树: 二叉树是一种树形结构,其中每个节点最多有两个子节点,我们可以通过递归的方式来创建一个二叉树。具体步骤如下: 首先,我们需要定义二叉树节点的结构体: ``` struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; ``` 然后,我们可以通过递归方式创建二叉树,示例代码如下: ``` TreeNode* createTree() { int val; cin &gt;&gt; val; // 输入节点的 if (val == -1) { // 如果为-1,表示该节点为空 return NULL; } TreeNode* root = new TreeNode(val); root-&gt;left = createTree(); // 递归创建左子树 root-&gt;right = createTree(); // 递归创建右子树 return root; } ``` 2. 先叉树: 先是指先访问节点本身,再遍其左子树和右子树。示例代码如下: ``` void preorderTraversal(TreeNode* root) { if (root == NULL) { return; } cout &lt;&lt; root-&gt;val &lt;&lt; &quot; &quot;; // 访问节点本身 preorderTraversal(root-&gt;left); // 遍左子树 preorderTraversal(root-&gt;right); // 遍右子树 } ``` 3. 中叉树1: 中是指先遍左子树,再访问节点本身,最后遍右子树。示例代码如下: ``` void inorderTraversal1(TreeNode* root) { if (root == NULL) { return; } inorderTraversal1(root-&gt;left); // 遍左子树 cout &lt;&lt; root-&gt;val &lt;&lt; &quot; &quot;; // 访问节点本身 inorderTraversal1(root-&gt;right); // 遍右子树 } ``` 4. 中叉树2: 与中1不同,这里给出一种非递归的中方法,需要使用到栈。示例代码如下: ``` void inorderTraversal2(TreeNode* root) { stack&lt;TreeNode*&gt; st; TreeNode* p = root; while (p != NULL || !st.empty()) { while (p != NULL) { st.push(p); p = p-&gt;left; } p = st.top(); st.pop(); cout &lt;&lt; p-&gt;val &lt;&lt; &quot; &quot;; p = p-&gt;right; } } ``` 5. 后叉树: 后是指先遍左子树,再遍右子树,最后访问节点本身。示例代码如下: ``` void postorderTraversal(TreeNode* root) { if (root == NULL) { return; } postorderTraversal(root-&gt;left); // 遍左子树 postorderTraversal(root-&gt;right); // 遍右子树 cout &lt;&lt; root-&gt;val &lt;&lt; &quot; &quot;; // 访问节点本身 } ``` 6. 层叉树: 层是指按照从上到下、从左到右的顺每个节点。需要使用到队列。示例代码如下: ``` void levelOrderTraversal(TreeNode* root) { if (root == NULL) { return; } queue&lt;TreeNode*&gt; q; q.push(root); while (!q.empty()) { TreeNode* node = q.front(); q.pop(); cout &lt;&lt; node-&gt;val &lt;&lt; &quot; &quot;; if (node-&gt;left != NULL) { q.push(node-&gt;left); } if (node-&gt;right != NULL) { q.push(node-&gt;right); } } } ``` 7. 求二叉树的深度: 二叉树的深度是指从根节点到最远叶子节点的最长路径上的节点数。可以使用递归方式求解。示例代码如下: ``` int maxDepth(TreeNode* root) { if (root == NULL) { return 0; } int leftDepth = maxDepth(root-&gt;left); int rightDepth = maxDepth(root-&gt;right); return max(leftDepth, rightDepth) + 1; } ``` 8. 退出

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值