代码随想录第18天:513.找树左下角的值、112. 路径总和 113.路径总和ii、106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

513:找树左下角的值

1、迭代法:

通过层序遍历,可以很容易的找到左下角的值。

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        	Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		int val = 0;
		while (!queue.isEmpty()) {
			List<Integer> list = new LinkedList<>();
			int len = queue.size();
			for (int i = 0; i < len; i++) {
				TreeNode node = queue.poll();
				list.add(node.val);
				if (node.left!=null) {
					queue.offer(node.left);
				}
				if (node.right!=null) {
					queue.offer(node.right);
				}
			}
			val = list.get(0);
		}
		return val;
    }
}

2、递归法:

1)递归函数参数和返回值:传入参数分别为结点和当前深度,通过全局变量来记录最大深度和左下角的值,因此没有返回值。

2)递归终止条件:当当前传入结点的左右子节点都为空的时候,如果当前深度大于所记录的最大深度,则更新最大深度值和result值并返回。

3)单层递归逻辑:遍历当前节点的左子树和右子树的最大深度对应的节点值。

class Solution {
		private int maxDepth = -1;
		private int result = 0;

    public int findBottomLeftValue(TreeNode root) {
			result = root.val;
      find(root, 0);
			return result;
    }

		private void find(TreeNode root, int depth) {
		if (root==null) {
			return;
		}
		if (root.left==null && root.right==null) {
			if (depth>maxDepth) {
				maxDepth = depth;
				result = root.val;
			}
			return;
		}
		if (root.left!=null) {
			depth++;
			find(root.left, depth);//递归
			depth--;
		}
		if (root.right!=null) {
			depth++;
			find(root.right, depth);//递归
			depth--;
		}
	}
}

112:路径总和

递归法:这里一开始的时候写的不对,后面看了题解之和发现是如下部分没有处理好

if (root.left!=null) {
			if (sum(root.left, tarhetSum, curSum+root.val)) {
				return true;
			}
		}

最开始写的时候直接写的

if (root.left!=null) {
			sum(root.left, tarhetSum, curSum+root.left.val);
		}
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
			return sum(root, targetSum, 0);
    }

    public boolean sum(TreeNode root, int tarhetSum, int curSum) {
		if (root==null) {
			return false;
		}
		
		if (root.left==null && root.right==null) {
			if ((curSum+root.val)==tarhetSum) {
				return true;
			}
		}
		if (root.left!=null) {
			if (sum(root.left, tarhetSum, curSum+root.val)) {
				return true;
			}
		}
		if (root.right!=null) {
			if (sum(root.right, tarhetSum, curSum+root.val)) {
				return true;
			}
		}
		return false;
	}
}

迭代法:仿照257:二叉树所有路径写的

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
				if (root==null) {
			return false;
		}
		Stack<Object> stack = new Stack<>();
		stack.push(root);
		stack.push(root.val);
		while (!stack.isEmpty()) {
			Integer val = (Integer) stack.pop();
			TreeNode node = (TreeNode) stack.pop();
			if (val==targetSum && node.left==null && node.right==null) {
				return true;
			}
			if (node.left!=null) {
				stack.push(node.left);
				stack.push(node.left.val+val);
			}
			if (node.right!=null) {
				stack.push(node.right);
				stack.push(node.right.val+val);
			}
		}
		return false;
    }
}

113:路径总和II

这个题和112的区别在于要输出所有的路径,这里需要注意的是递归出口的时候得重新new一个ArrayList对象,貌似是因为Java是引用传递,那样当list回溯的话,值会发生改变。

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
      	List<List<Integer>> res = new ArrayList<>();
		List<Integer> list = new ArrayList<>();
		if(root==null) return res;
		list.add(root.val);
		path(root, targetSum-root.val, list, res);
		return res;
    }

		public void path(TreeNode root, int targetSum,
			List<Integer> list, List<List<Integer>> res) {
		if (root==null) {
			return;
		}
		if (root.left==null && root.right==null) {
			if (targetSum==0) {
				res.add(new ArrayList<>(list));
			}
			return;
		}
		if (root.left!=null) {
			list.add(root.left.val);
			path(root.left, targetSum-root.left.val, list, res);
			list.remove(list.size()-1);
		}
		if (root.right!=null) {
			list.add(root.right.val);
			path(root.right, targetSum-root.right.val, list, res);
			list.remove(list.size()-1);
		}
	}
}

106:从中序和后序遍历序列构造二叉树

第一步:先从后序遍历中找到根节点;第二步:根据根节点在中序遍历中找到对应位置,计算出左子树的长度;第三步根据左子树的长度调节下一次遍历的begin、end、left和right。遵循左闭右开原则。

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder.length==0 || postorder.length==0) {
			return null;
		}
		return build(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }

    public TreeNode build(int[] inorder, int begin, int end, 
			int[] postorder,int left, int right) {
		if (begin>=end && left>=right) {
			return null;
		}
		int v = postorder[right-1];
		TreeNode root = new TreeNode(v);
		int leftLen = -1;
		for (int i = begin; i < end; i++) {
			if (inorder[i]==v) {
				leftLen = i-begin;
			}
		}
		root.left = build(inorder, begin, begin+leftLen, postorder, left, left+leftLen);
		root.right = build(inorder, begin+leftLen+1, end, postorder, left+leftLen, right-1);
		return root;
	}
}

105:从前序和中序遍历序列构造二叉树

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder.length==0 || inorder.length==0) {
			return null;
		}
		return build(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }

    public TreeNode build(int[] preorder, int begin, int end, 
			int[] inorder,int left, int right) {
		if (begin>=end && left>=right) {
			return null;
		}
		int v = preorder[begin];
		TreeNode root = new TreeNode(v);
		int leftLen = -1;
		for (int i = left; i < right; i++) {
			if (inorder[i]==v) {
				leftLen = i-left;
			}
		}
		root.left = build(preorder, begin+1, begin+leftLen+1, inorder, left, left+leftLen);
		root.right = build(preorder, begin+leftLen+1, end, inorder, left+leftLen+1, right);
		return root;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值