• [LeetCode#110, 112, 113]Balanced Binary Tree, Path Sum, Path Sum II


    Problem 1 [Balanced Binary Tree]

    Given a binary tree, determine if it is height-balanced.

    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

    Problem 2 [Path Sum]

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /        
            7    2      1

    Problem 3 [Path Sum II]

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /      / 
            7    2  5   1



    The three problems  are very easy at some extent, but they differ with each other, regarding the proper mechanism of passing answer set and arguments.

    The three problems include two very important issues in writing a recursion program. 

    1. How to pass the arguments to next level recursion? 

    2. How to return the answer set? 

    In problem1: (feedback to root level)

    In order to test if a tree is a balance binary tree, we need to get the height of left-sub tree and right-sub tree.  Can we do it in this way ?

    get_height(..., int left_tree_height, ...)

    Absolutely no, Java pass arguments by value(the change in low-level recursion is just within its own scope).Thus we have to use other choices. 

    Choice 1: Record the height in an array(ArrayList), but we have only one height value to pass between two adjacent recursion levels. It seems to complex the problem.

    Choice 2: Return height as a return value. It seems very reasonable, but how could we pass the vlidation information back(we check along the recursion path). We have already use height as return value, we can't return a boolean value at the same time.  There is a way to solve this problem: Since we pass height, and the height would never be a negative number, how about using "-1" to indicate invalidation. 

    My solution:

    public class Solution {
        public boolean isBalanced(TreeNode root) {
            if (root == null) //an empty tree
                return true;
                
            if (getTreeHeight(root) == -1)
                return false;
            else
                return true;
        }
        
        private int getTreeHeight(TreeNode cur_root) {
            
            if (cur_root == null)
                return 0;
            
            int left_height = getTreeHeight(cur_root.left);
            int right_height = getTreeHeight(cur_root.right);
            
            if (left_height == -1 || right_height == -1) //the -1 represent violation happens in the sub-tree
                return -1;
            
            if (Math.abs(left_height - right_height) > 1) //the violation happens in the current tree 
                return -1; 
            
            return left_height > right_height ? left_height + 1 : right_height + 1;
            //return the new height to the pre level recursion
        }
    }

    In problem 2: (feedback to root level)

    Since we just care about whether there exists an path equal to the sum, we could directly use a boolean value as return value. 

    My solution: 

    public class Solution {
        public boolean hasPathSum(TreeNode root, int sum) {
            
            if (root == null)
                return false;
            
            return helper(root, sum);
        }
        
        private boolean helper(TreeNode cur_root, int sub_sum) {
            
            if (cur_root == null)
                return false;
            
            if (cur_root.left == null && cur_root.right == null) { //reach the leaf node
                if (cur_root.val == sub_sum)
                    return true;
            }
            
            return helper(cur_root.left, sub_sum - cur_root.val) || helper(cur_root.right, sub_sum - cur_root.val); 
        }
    }

    In problem 3:(no need to feed back to root level, directly add answer to result set at base level)

    This problem is an advanced version of problem3,  it includes many skills we should master when writing an useful recursion program.  We should first note following facts:

    1. we need a global answer set, thus once we have searched out a solution, we could directly add the solution into the answer set. The effects scope of this set should be globally accessiable. This means at each recursion branches, it could be updated, and the effects is in global scope. We pass it as an argument. 

    public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
            
            ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>> ();
            if (root == null)
                return ret;
            
            ArrayList<Integer> ans = new ArrayList<Integer> ();
            helper(root, sum, ans ,ret);
            
            return ret; 
        }

    2. We should keep the path's previous information before reaching the current node. We should be able to mainpulate on the information, and pass it to next recursion level. The big problem comes out : if we manipulate on the same object(list), this could be a disaster. Since each recursion level has two sparate searching branches. 

    The solution: we make a copy of passed in list, thus we can use the information recorded in the list, without affecting other searching branches. <All we want to get and use is the information, not the list>

     ArrayList<Integer> left_ans_copy = new ArrayList<Integer> (ans);
     ArrayList<Integer> right_ans_copy = new ArrayList<Integer> (ans);

    My solution:

    public class Solution {
        public boolean isBalanced(TreeNode root) {
            if (root == null) //an empty tree
                return true;
                
            if (getTreeHeight(root) == -1)
                return false;
            else
                return true;
        }
        
        private int getTreeHeight(TreeNode cur_root) {
            
            if (cur_root == null)
                return 0;
            
            int left_height = getTreeHeight(cur_root.left);
            int right_height = getTreeHeight(cur_root.right);
            
            if (left_height == -1 || right_height == -1) //the -1 represent violation happens in the sub-tree
                return -1;
            
            if (Math.abs(left_height - right_height) > 1) //the violation happens in the current tree 
                return -1; 
            
            return left_height > right_height ? left_height + 1 : right_height + 1;
            //return the new height to the pre level recursion
        }
    }
  • 相关阅读:
    SqlServer无备份下误删数据恢复
    vue——storage命名冲突问题解决 前端
    vue——bus总线 前端
    elementUI——elform表单验证,表单项切换显示,校验错误信息未清除 前端
    elementUI——input输入框,设置autocomplete="off"无效问题 前端
    elementUI——table空单元格自动填充占位符,编辑后数据更新视图未更新问题 前端
    vue——爷孙组件之间通信 前端
    vue——路由守卫beforeEach,next(), next('/'), next({...to, repalce: true})说明及实例问题 前端
    elementUI——zindex自增问题 前端
    vue——vuecli3项目打包时区分环境以及环境变量undefined问题解决 前端
  • 原文地址:https://www.cnblogs.com/airwindow/p/4214460.html
Copyright © 2020-2023  润新知