Leetcode 513:
https://leetcode.com/problems/find-bottom-left-tree-value/description/
题目的第一想法:
这道题我的直觉是做层序遍历,然后记录下每层的第一个值然后返回。做完是可以成立的。写法如下
class Solution {
public int findBottomLeftValue(TreeNode root) {
Deque<TreeNode> q = new LinkedList<>();
int rvalue = 0;
q.add(root);
while(!q.isEmpty()){
int size = q.size();
boolean first = true;
while(size > 0){
TreeNode temp = q.poll();
if(temp.left != null){
q.offer(temp.left);
}
if(temp.right != null){
q.offer(temp.right);
}
if(first){
rvalue = temp.val;
first = false;
}
size--;
}
}
return rvalue;
}
}
看完代码随想录之后的想法:
这道题还有一个更快的解法,是做一个正常的遍历然后记录最深层的数据。这样的话时间复杂度一样,但空间复杂度可以变得更少(如果层序遍历使用了queue来记录当前层的Node的话)。
Leetcode 112&113:
https://leetcode.com/problems/path-sum/
https://leetcode.com/problems/path-sum-ii/
题目的第一想法:
112这题我最一开始的想法就是递归,然后条件是如果为root为null且targetSum为0就返回true不然就递归fun(root.left, targetSum - root.val) || fun(targetSum - root.right)。但这样写有一个问题。即无法处理当一个node只有左或只有右node时的情况,因为递归会走到null然后返回,和判断树最小高度的问题很类似。因此,我们在这种情况做一个判断leaf的条件会比直接依靠null来判断要好很多。以下为112的写法
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
else if(root.right == null && root.left == null && targetSum - root.val == 0){
return true;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
}
接下来说一说113,这道题比起112要稍微复杂一些,因为我们需要记录下所有路径的值。那么在什么时候加入又在什么时候剔除list里面的值就变成了一个问题。这个问题大体的写法是遍历所有的node,然后沿途加入当前node的数值。最后当targetSum为0时把list内的值加入到rlists里面去。那么何时可以加入何时剔除数值呢。我最一开始的想法是,在当前层加入,然后在上一层剔除。很可惜这是不可能实现的,因为我们不可避免的会进入root为null的情况里。此时,我们是无法加入任何数值进去,而上一层总会剔除一个值。所以我们会不可避免的多剔除一个数值。所以我们需要当前层剔除当前层加入的数值。如此,我们才能保证加入的数值可以被正确的剔除。写法如下
class Solution {
List<List<Integer>> rlists = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
Deque<Integer> list = new LinkedList<>();
pathSum(root, targetSum, list);
return rlists;
}
public void pathSum(TreeNode root, int targetSum, Deque<Integer> list){
if(root == null){
return;
}else if(root.left == null && root.right == null && targetSum - root.val == 0){
list.add(root.val);
rlists.add(new LinkedList<Integer>(list));
list.pollLast();
return;
}else if(root.left == null && root.right == null){
return;
}
list.add(root.val);
pathSum(root.left, targetSum - root.val, list);
pathSum(root.right, targetSum - root.val, list);
list.pollLast();
}
}
Leetcode 106:
https://leetcode.com/problems/find-bottom-left-tree-value/description/
题目的第一想法:
这道题没什么第一想法。感觉脑子并没能第一时间整理出一个规整的走法出来。
看完代码随想录之后的想法:
我觉得这个算法还是挺难自己想出来的。大概有几个需要注意的点,一是起点和终点不能一样。因为终点会--。其次leftover(因为index是从0开始算的,假设leftover有三个,start+leftover就是3)本身就多了一个,所以当起点时不需要再+1了。
class Solution {
HashMap<Integer, Integer> hash = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
for(int i = 0; i < inorder.length; i++){
hash.put(inorder[i], i);
}
TreeNode root = buildTree(inorder, 0, inorder.length, postorder, 0, postorder.length);
return root;
}
public TreeNode buildTree(int[] inorder, int instart, int inend, int[] postorder, int postart, int poend){
if(instart >= inend || postart >= poend){
return null;
}
int rootin = hash.get(postorder[poend - 1]);
TreeNode root = new TreeNode(postorder[poend - 1]);
int leftover = rootin - instart;
root.left = buildTree(inorder, instart, rootin, postorder, postart, postart + leftover);
root.right = buildTree(inorder, rootin + 1, inend, postorder, postart + leftover, poend - 1);
return root;
}
}