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