【算法题型总结】--4、树

1、NC117 合并二叉树

public TreeNode mergeTrees (TreeNode t1, TreeNode t2)

 

 

public class Solution {
    /**
     * 
     * @param t1 TreeNode类 
     * @param t2 TreeNode类 
     * @return TreeNode类
     */
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) return null;
        if (t1 == null || t2 == null) return t1 == null ? t2 : t1;
        // 此时 t1、t2 均不为 null
        // 合并节点的值
        t1.val = t1.val + t2.val;
        // 合并左子树
        t1.left = mergeTrees(t1.left, t2.left);
        // 合并右子树
        t1.right = mergeTrees(t1.right, t2.right);
        return t1;
    }
}

2、NC161 二叉树的中序遍历

public int[] inorderTraversal (TreeNode root)

解法1:递归

public class Solution {
    // 中序遍历的递归写法 思路清晰但是不够高效
    ArrayList<Integer> list = new ArrayList<>();
    public int[] inorderTraversal (TreeNode root) {
        recur(root);
        return list.stream().mapToInt(Integer::valueOf).toArray();
    }
    public void recur(TreeNode root) {
        if (root == null) return;
        recur(root.left);
        list.add(root.val);
        recur(root.right);
    }
}

解法2:非递归(往左找,出栈往右找)

public int[] inorderTraversal (TreeNode root) {
        ArrayList<Integer> arrList=new ArrayList<>();
        Stack<TreeNode> stack=new Stack<>();
        while(root!=null || !stack.isEmpty()){
            while(root!=null){
                stack.push(root);
                root=root.left;
            }
                root=stack.pop();
                arrList.add(root.val);
                root=root.right;
        }
        return arrList.stream().mapToInt(Integer::valueOf).toArray();
    }

3、NC72 二叉树的镜像

public TreeNode Mirror (TreeNode pRoot)

public TreeNode Mirror (TreeNode pRoot) {
        if(pRoot == null) {
            return null;
        }
        if(pRoot.left == null && pRoot.right == null) {
            return pRoot;
        }
        TreeNode L = Mirror(pRoot.left);
        TreeNode R = Mirror(pRoot.right);
        pRoot.left = R;
        pRoot.right = L;
        return pRoot;
    }

4、NC13 二叉树的最大深度

public int maxDepth (TreeNode root)

 

 解法1:非递归-层次遍历+队列

public int maxDepth (TreeNode root) {
        //通过层次遍历计算二叉树的深度
        if(root==null) return 0;
        Queue<TreeNode>queue=new LinkedList<>();
        queue.offer(root);
        int level=0,size;
        while(!queue.isEmpty()){
            size=queue.size();
            for(int i=0;i<size;i++){
                TreeNode node=queue.poll();
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
            level++;
        }
        return level;
    }

解法2:递归

import java.util.*; 
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        if(root==null){
            return 0;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
         
        return 1 + Math.max(left,right);
    }
}

5、NC136 输出二叉树的右视图

public int[] solve (int[] xianxu, int[] zhongxu)

 

 构造出二叉树之后再用队列找到每层的最后一个节点

HashMap<Integer,Integer> inOrderHashMap = new HashMap<>();
    public int[] solve (int[] xianxu, int[] zhongxu) {
        // write code here
        if (xianxu==null||zhongxu==null||xianxu.length==0||zhongxu.length==0) return new int[0];
        for (int i = 0; i < zhongxu.length; i++) {
            inOrderHashMap.put(zhongxu[i],i);
        }
        TreeNode root = buildTree(xianxu, 0, xianxu.length - 1, inOrderHashMap, 0, zhongxu.length - 1);
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.offer(root);
        int[] res = new int[xianxu.length];
        int count =0;
        while (!queue.isEmpty()){
            //拿到当前层元素个数
            int len = queue.size();
            System.out.println(len);
            for (int i = 0; i < len; i++) {
                TreeNode node = queue.poll();
                if (node.left!=null) queue.offer(node.left);
                if (node.right!=null) queue.offer(node.right);
                //到最后一个元素了
                if (i==len-1) res[count++] = node.val;
            }
        }
        //count是有效数组元素 0下标开始 跟左闭右开刚好对冲
        return Arrays.copyOfRange(res,0,count);
    }
    //inOrder: [inLeft,rootIndex-1] rootIndex [rootIndex+1,inRight]
    //preOrder: preLeft [preLeft+1,preLeft+rootIndex-inLeft] [preLeft+rootIndex-inLeft+1,preRight]
    private TreeNode buildTree(int[] xianxu, int preLeft, int preRight, HashMap<Integer, Integer> inOrderHashMap, int inLeft, int inRight) {
        //preLeft == preRight时 也要执行的 --叶子节点罢了
        if (preLeft>preRight||inLeft>inRight) return null;
        int rootIndex = inOrderHashMap.get(xianxu[preLeft]);
        TreeNode root = new TreeNode(xianxu[preLeft]);
        root.left = buildTree(xianxu, preLeft + 1, preLeft + rootIndex - inLeft, inOrderHashMap, inLeft, rootIndex - 1);
        root.right = buildTree(xianxu,preLeft+rootIndex-inLeft+1,preRight,inOrderHashMap,rootIndex+1,inRight);
        return root;
    }

6、NC102 在二叉树中找到两个节点的最近公共祖先

public int lowestCommonAncestor (TreeNode root, int o1, int o2)

 

  public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        if(root.val == o1 || root.val == o2){
            return root.val;
        }
        TreeNode treeNode = order(root, o1, o2);
        return treeNode.val;
    }
    public TreeNode order(TreeNode root, int o1, int o2){
        if(root == null)
            return null;
        if(root.val == o1 || root.val == o2)
            return root;
        TreeNode left = order(root.left, o1, o2);
        TreeNode right = order(root.right, o1, o2);
         
        if(left != null && right != null)
            return root;
        if(left == null && right == null)
            return null;
         
        return left == null? right: left;
    }

7、NC15 求二叉树的层序遍历

public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root)

方法:队列

import java.util.*;
 
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
 
public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        if (root == null) {
            return new ArrayList<>();
        }
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<Integer> temp = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        Queue<TreeNode> mid = new LinkedList<>();
        while(!queue.isEmpty()) {
            TreeNode node = queue.poll();
            temp.add(node.val);
            if (node.left != null) {
                mid.add(node.left);
            }
            if (node.right != null) {
                mid.add(node.right);
            }
            if (queue.isEmpty()) {
                queue = mid;
                mid = new LinkedList<>();
                res.add(temp);
                temp = new ArrayList<>();
            }
        }
        return res;
    }
}

8、NC45 实现二叉树先序、中序、后序遍历

public int[][] threeOrders (TreeNode root)

 

 

 解法1:递归

import java.util.*;
 
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
 
public class Solution {
    /**
     * 
     * @param root TreeNode类 the root of binary tree
     * @return int整型二维数组
     */
    public int[][] threeOrders (TreeNode root) {
        if(root==null){
            return new int[0][0];
        }
        int[][] res = new int[3][];
        //先序
        List<Integer> list1 = new ArrayList<Integer>();
        first(root,list1);
        res[0] = list1.stream().mapToInt(Integer::intValue).toArray();
                
        //中序
        List<Integer> list2 = new ArrayList<Integer>();
        second(root,list2);
        res[1] = list2.stream().mapToInt(Integer::intValue).toArray();
         
        //后序
        List<Integer> list3 = new ArrayList<Integer>();
        third(root,list3);
        res[2] = list3.stream().mapToInt(Integer::intValue).toArray();
         
        return res;
    }
     
    private void first(TreeNode root,List<Integer> list){
        if(root==null){
            return;
        }
        list.add(root.val);
        first(root.left,list);
        first(root.right,list);
    }
     
    private void second(TreeNode root,List<Integer> list){
        if(root==null){
            return;
        }
        second(root.left,list);
        list.add(root.val);
        second(root.right,list);
    }
     
    private void third(TreeNode root,List<Integer> list){
        if(root==null){
            return;
        }
        third(root.left,list);
        third(root.right,list);
        list.add(root.val);
    }
     

方法2:非递归

    /**
     * 使用非递归的方法解决
     * @param root
     * @return
     */
    public int[][] threeOrders (TreeNode root) {
        if(root==null){
            return new int[0][0];
        }
        List<Integer> list1=new ArrayList<>();
        List<Integer> list2=new ArrayList<>();
        List<Integer> list3=new ArrayList<>();
        preOrder(list1,root);
        midOrder(list2,root);
        afterOrder(list3,root);
        int len = list1.size();
        int[][] res=new int[3][len];
        for (int i = 0; i < len; i++) {
            res[0][i]=list1.get(i);
        }
        for (int i = 0; i < len; i++) {
            res[1][i]=list2.get(i);
        }
        for (int i = 0; i < len; i++) {
            res[2][i]=list3.get(i);
        }
        return res;
    }
 
    /**
     * 先序遍历
     * @param list1
     * @param root
     */
    private void preOrder(List<Integer> list1, TreeNode root) {
        Stack<TreeNode> stack=new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()){
            TreeNode node = stack.pop();
            list1.add(node.val);
            if(node.right!=null){
                stack.push(node.right);
            }
            if(node.left!=null){
                stack.push(node.left);
            }
        }
    }
    /**
     * 中序遍历
     * @param list2
     * @param root
     */
    private void midOrder(List<Integer> list2, TreeNode root) {
        Stack<TreeNode> stack=new Stack<>();
        while (!stack.isEmpty() || root!=null){
            while (root!=null){
                stack.push(root);
                root=root.left;
            }
            TreeNode node = stack.pop();
            list2.add(node.val);
            if(node.right!=null){
                root=node.right;
            }
        }
    }
    /**
     * 后序遍历
     * @param list3
     * @param root
     */
    private void afterOrder(List<Integer> list3, TreeNode root) {
        Stack<TreeNode> stack=new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()){
            TreeNode node = stack.pop();
            list3.add(node.val);
            if(node.left!=null){
                stack.push(node.left);
            }
            if(node.right!=null){
                stack.push(node.right);
            }
        }
        Collections.reverse(list3);
    }

9、判断二叉树是否对称

public boolean isSymmetric (TreeNode root)

 

 

 方法1:递归

public class Solution {
    public boolean isSymmetric (TreeNode root) {
        if (root == null) return true;
        return recur(root.left, root.right);
    }
    // 递归辅助函数
    public boolean recur(TreeNode left, TreeNode right) {
        if (left == null && right == null) return true;
        else if (left != null && right == null) return false;
        else if (left == null && right != null) return false;
        else return left.val == right.val && recur(left.left, right.right) && recur(left.right, right.left);
    }
}

方法2:层次遍历-Deque

public boolean isSymmetric (TreeNode root) {
    if (root == null) return true;
    Deque<TreeNode> queue = new LinkedList<>();
    queue.addLast(root.left);
    queue.addLast(root.right);
    while (!queue.isEmpty()) {
        TreeNode left = queue.pollLast();
        TreeNode right = queue.pollLast();
        if (left == null && right == null) continue;
        if (left == null || right == null) return false;
        if (left.val != right.val) return false;
     //队列需要添加4个元素 queue.addFirst(left.left); queue.addFirst(right.right); queue.addFirst(left.right); queue.addFirst(right.left); }
return true; }

10、NC62 平衡二叉树

public boolean IsBalanced_Solution(TreeNode root)

 

 

 

public class Solution {
    private boolean flag;
     
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) {
            return true;
        }
        flag = true;
        getDepth(root);
        return flag;
    }
     
    public int getDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int L = getDepth(root.left);
        int R = getDepth(root.right);
        if(Math.abs(L - R) > 1) {
            flag = false;
            return -1;
        }
        return Math.max(L, R) + 1;
    }
}

//平衡二叉树要求:左右子树的深度差不超过1,并且左右子树也是平衡二叉树(空树也可以理解成平衡二叉树)
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null) return true;
        return (Math.abs(depth(root.left)-depth(root.right))<=1)
            && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
    public int depth(TreeNode root){
        if(root==null) return 0;
        return Math.max(depth(root.left),depth(root.right))+1;
    }
}

import java.util.*;
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
         
        if(root == null){
            return true;
        }
         
        //判断两个子树的高度差绝对值是否超过1
        if(Math.abs(getTreeDeep(root.left) - getTreeDeep(root.right)) > 1){
            return false;
        }
         
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
     
    //计算二叉树的深度
    public int getTreeDeep(TreeNode root){
        if(root == null){
            return 0;
        }
         
        int leftNum = 1;
        int rightNum = 1;
         
        if(root.left != null){
            leftNum += getTreeDeep(root.left);
        }
        if(root.right != null){
            rightNum += getTreeDeep(root.right);
        }
         
        return leftNum >= rightNum ? leftNum : rightNum;
    }
}

总结:左右子树也要满足&左右子树深度之差不超过1

11、NC9 二叉树中是否存在节点和为指定值的路径---dfs/回溯

public boolean hasPathSum (TreeNode root, int sum)

  解法:回溯-结束条件、路径、选择列表

public class Solution {
    private ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        ArrayList<Integer> list = new ArrayList<>();
        recur(root, sum, list);
        return lists;
    }
    public void recur(TreeNode root, int sum, ArrayList<Integer> list) {
        if (root == null) return;
        list.add(root.val); // 先加入list中
        if (root.left == null && root.right == null) { // 到达叶子结点
            if (sum == root.val) lists.add(new ArrayList<Integer>(list));
            list.remove(list.size()-1); // 移除当前结点,找到 叶子节点就移除,让list没有叶子节点
        } else {
            recur(root.left, sum - root.val, list);
            recur(root.right, sum - root.val, list);
            list.remove(list.size()-1); // 递归返回时移除上一个结点
        }
    }
}

类似方法

public class Solution {
    private ArrayList<ArrayList<Integer>> res;
    public void getPath(TreeNode root, int sum, ArrayList<Integer> temp){
        if(root == null) return ;
        if(root.left == null && root.right == null){
            if(sum - root.val == 0){
                temp.add(new Integer(root.val));
                //注意此处,temp为传入的引用,写入总的记录时候要重新建一个对象,因为后面需要对temp修改。
                res.add(new ArrayList<Integer>(temp));
                //记录之后,需要回溯temp为上一个状态,继续走右分支。
                temp.remove(temp.size()-1);
            }
            return ;
        }
        temp.add(new Integer(root.val));
        getPath(root.left, sum-root.val, temp);
        getPath(root.right, sum-root.val, temp);
        //左右分支结束之后需要恢复到上一层递归时候的状态,以便上一层递归选择不同的分支。
        temp.remove(temp.size()-1); 
    }
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        // write code here
        res = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> temp = new ArrayList<Integer>();
        getPath(root, sum, temp);
        return res;
    }
}

1

 方法1:递归--结束条件,选择列表,路径做选择

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

方法2:dfs

 public boolean hasPathSum (TreeNode root, int sum) {
        // write code here
        return dfs(root,sum);
    }
    private boolean dfs(TreeNode root, int sum) {
        if(root == null) return false;
        sum -= root.val;
        if(root.left == null && root.right == null && sum == 0) return true;
        return dfs(root.left,sum) || dfs(root.right,sum);
    }

12、NC5 二叉树根节点到叶子节点的所有路径和---dfs

public int sumNumbers (TreeNode root) 

解法1:非递归

private int val = 0;
    public int sumNumbers (TreeNode root) {
        // write code here
        if(root==null)
            return 0;
        //dfs(root,0);
        Stack<TreeNode> st = new Stack<>();//使用栈,将从根节点往下的值依次相加,直到左右子树均为空且栈空,则表示到达最底部。
        st.push(root);
        while(!st.isEmpty()){
            TreeNode p = st.pop();
            if(p.left==null && p.right==null){
                val = val +p.val; //val计算路径和
            }else{
                if(p.left!=null){
                    p.left.val = p.val *10 + p.left.val;
                    st.push(p.left);
                }
                if(p.right!=null){
                    p.right.val = p.val *10 + p.right.val;
                    st.push(p.right);
                }
            }
        }
        return val;
    }

方法2:回溯-结束条件 、路径、选择列表

import java.util.*;
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
public class Solution {
    private int res = 0;
    /**
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int sumNumbers (TreeNode root) {
        if(root==null){
            return 0;
        }
        process(root,0);
        return res;
    }
    private void process(TreeNode root,int agg){
        agg = agg*10 + root.val;
        if(root.left==null&&root.right==null){
            res = res + agg;
        }else{
            if(root.left!=null){
                process(root.left,agg);
            }
            if(root.right!=null){
                process(root.right,agg);
            }
        }
    } 
}

13、NC11 将升序数组转化为平衡二叉搜索

public TreeNode sortedArrayToBST (int[] num)

 

 

 解法1:递归&选择中间的作为根节点

public class Solution22 {
    public TreeNode sortedArrayToBST(int[] num) {
        if(num==null||num.length==0)
            return null;
        return sorted(num,0,num.length-1);
    }
     
    public TreeNode sorted(int[] num,int left,int right) {
         if(left>right)
             return null;
         int mid =(left+right+1)/2;
         int num1 =num[mid];
         TreeNode node = new TreeNode(num1);
         node.left =sorted(num,left,mid-1);
         node.right = sorted(num,mid+1,right);
         return node;
    }
}

14、NC8 二叉树根节点到叶子节点和为指定值的路径

public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum)

 

 

 解法:回溯-结束条件、路径、选择列表

public class Solution {
    private ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        ArrayList<Integer> list = new ArrayList<>();
        recur(root, sum, list);
        return lists;
    }
    public void recur(TreeNode root, int sum, ArrayList<Integer> list) {
        if (root == null) return;
        list.add(root.val); // 先加入list中
        if (root.left == null && root.right == null) { // 到达叶子结点
            if (sum == root.val) lists.add(new ArrayList<Integer>(list));
            list.remove(list.size()-1); // 移除当前结点,找到 叶子节点就移除,让list没有叶子节点
        } else {
            recur(root.left, sum - root.val, list);
            recur(root.right, sum - root.val, list);
            list.remove(list.size()-1); // 递归返回时移除上一个结点
        }
    }
}

类似方法

public class Solution {
    private ArrayList<ArrayList<Integer>> res;
    public void getPath(TreeNode root, int sum, ArrayList<Integer> temp){
        if(root == null) return ;
        if(root.left == null && root.right == null){
            if(sum - root.val == 0){
                temp.add(new Integer(root.val));
                //注意此处,temp为传入的引用,写入总的记录时候要重新建一个对象,因为后面需要对temp修改。
                res.add(new ArrayList<Integer>(temp));
                //记录之后,需要回溯temp为上一个状态,继续走右分支。
                temp.remove(temp.size()-1);
            }
            return ;
        }
        temp.add(new Integer(root.val));
        getPath(root.left, sum-root.val, temp);
        getPath(root.right, sum-root.val, temp);
        //左右分支结束之后需要恢复到上一层递归时候的状态,以便上一层递归选择不同的分支。
        temp.remove(temp.size()-1); 
    }
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        // write code here
        res = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> temp = new ArrayList<Integer>();
        getPath(root, sum, temp);
        return res;
    }
}

15、NC6 二叉树的最大路径和

public int maxPathSum (TreeNode root)

 

 

 

 

 

 

 解法:回溯-结束条件,记录路径,做选择

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxPathSum (TreeNode root) {
        // write code here
        if(root == null){return 0;}
        int[] res = {0x80000000};
        subTreeMax(root, res);
        return res[0];
    }
     
    private int subTreeMax(TreeNode root, int[] res){
        // subTreeMax()函数 1.计算包含子树根节点root的最大非折返路径和。
        // 所谓非折返,就是路径不能同时包含左右子树。折返路径就是左子树+root+右子树
        // 2. 根据最大折返路径与最大非折返路径更新最大路径和。
        if(root == null){return 0;}
        int leftMax = subTreeMax(root.left, res);
        int rightMax = subTreeMax(root.right, res);
        int childMax = Math.max(leftMax, rightMax);
        int ret = childMax > 0? childMax + root.val: root.val;
        int leftRootRight = leftMax + root.val + rightMax;
        res[0] = Math.max(res[0], Math.max(leftRootRight, ret));//避免有负的
        return ret;
    }
}

16、NC60 判断一棵二叉树是否为搜索二叉树

public boolean[] judgeIt (TreeNode root)

 

 

 解法:回溯

import java.util.*;
 
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
 
public class Solution {
    /**
     * 
     * @param root TreeNode类 the root
     * @return bool布尔型一维数组
     */
     
    boolean searchFlag= true;
    boolean completeFlag = true;
    int num=Integer.MIN_VALUE;
    Stack<Integer> stack = new Stack<>(); 
     
    public boolean[] judgeIt (TreeNode root) {
        dfs(root,0);
        return new boolean[]{searchFlag, completeFlag};
    }
     
    public void dfs(TreeNode root, int len) {
        //如果两者为false,则开始剪枝
        if(!searchFlag && !completeFlag) return ;
        if(root==null){
            //判断是否是完全二叉树:
            //如果是完全二叉树,那么每个空子叶节点所在路径长度差值不得大于1,并且左子节点路径长度必须大于等于右子节点路径长度
            //当节点为空说明是一个空子叶节点,此时将该路径长度与前一个路径(上一个空子节点路径)的长度做比较,如果大于则不是完全二叉树
            if(stack.size()>=1 && stack.peek()<len) completeFlag=false;
            stack.add(len);
            return ;
        } 
         
        dfs(root.left, len+1);
        //判断是否是搜索二叉树:
        //如果是搜索二叉树,那么中序遍历的结果应该是递增关系。
        //如果此访问节点值小于上一个访问节点值,说明破坏了递增规律,则不是搜索二叉树。
        if(root.val>=num){
            num = root.val;
        }else {
            searchFlag=false;
        }
        dfs(root.right,len+1);
    }
}

其他

import java.util.*;
 
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */
 
public class Solution {
    /**
     *
     * @param root TreeNode类 the root
     * @return bool布尔型一维数组
     */
    long pre = Long.MIN_VALUE;
    public boolean[] judgeIt (TreeNode root) {
        // write code here
        return new boolean[]{isSBT(root),isCBT(root)};
    }
 
    /**
     * 判断一棵二叉树是否为搜索二叉树,只要改写一个二叉树中序遍历,在遍历的过程中看节点值是否都是递增的即可。
     * @param root
     * @return
     */
    public boolean isSBT(TreeNode root) {
        if (root == null) {
            return  true;
        }
        if(!isSBT(root.left)) {
            return false;
        }
        if (root.val <= pre) {
            return false;
        }
        pre = root.val;
        return isSBT(root.right);
    }
 
    /**
     *
     * 判断一棵二叉树是否为完全二叉树,依据以下标准会使判断过程变得简单且易实现。
     * 1.按层遍历二叉树,从每层的左边向右边依次遍历所有的节点。
     * 2.如果当前节点有右孩子节点,但没有左孩子节点,则直接返回 false。
     * 3.如果当前节点并不是左右孩子节点全有,那么之后的节点必须都为叶节点,否则返回false。
     * 4.遍历过程中如果不返回 false,则遍历结束后返回 true。
     * @param root
     * @return
     */
    public boolean isCBT(TreeNode root) {
        if (root == null) {
            return true;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        boolean leaf = false;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                //如果当前节点并不是左右孩子节点全有,那么之后的节点必须都为叶节点
                if (leaf && (node.left != null || node.right != null)) {
                    return false;
                }
                //如果当前节点有右孩子节点,但没有左孩子节点,则直接返回 false
                if (node.left == null && node.right != null) {
                    return false;
                }
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                } else {
                    leaf = true;
                }
            }
        }
        return true;
 
    }
}

17、NC12 重建二叉树

public TreeNode reConstructBinaryTree(int [] pre,int [] in)

 

 

 

 解法1:

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
        return root;
    }
    //前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
    private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
         
        if(startPre>endPre||startIn>endIn)
            return null;
        TreeNode root=new TreeNode(pre[startPre]);
         
        for(int i=startIn;i<=endIn;i++)
            if(in[i]==pre[startPre]){
                root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
                root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
                break;
            }
                 
        return root;
    }
}

类似:

public class Solution {
    int i = 0;
    public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
        if(i == pre.length && vin.length == 0) return null;
        TreeNode root = null;
        for(int j = 0; j < vin.length; j++) {
            if(pre[i] == vin[j]) {
                root = new TreeNode(pre[i]);
                i++;
                root.left = reConstructBinaryTree(pre,Arrays.copyOfRange(vin,0,j));
                root.right = reConstructBinaryTree(pre,Arrays.copyOfRange(vin,j+1,vin.length));
                break;
            }
        }
        return root;
    }
}

18、NC14 按之字形顺序打印二叉树

public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot)

 

 

 

import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Collections;
 
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer> > res =new ArrayList<>();
        if(pRoot == null){
            return res;
        }
        Queue<TreeNode> queue =new LinkedList<TreeNode>();
        queue.offer(pRoot);
        boolean b = true;
        while(!queue.isEmpty()){
            int num = queue.size();
            ArrayList<Integer> temp = new ArrayList<>();
            for(int i = 0;i< num;i++){
                TreeNode t = queue.poll();
                if(t.left != null){
                    queue.offer(t.left);
                }
                if(t.right != null){
                    queue.offer(t.right);
                }
                temp.add(t.val);
            }
            if(!b){
                Collections.reverse(temp);
            }
            b = !b;
            res.add(temp);
             
        }
        return res;
    }
}

19、NC81 二叉搜索树的第k个结点

TreeNode KthNode(TreeNode pRoot, int k)

import java.util.*;
 
// 中序遍历
public class Solution {
    TreeNode KthNode(TreeNode pRoot, int k) {
        if(pRoot==null) return null;
        int count = 0;
        List<TreeNode> stack = new ArrayList<>();
        while(!stack.isEmpty() || pRoot!=null) {
            if(pRoot!=null) {// 先往左找
                stack.add(pRoot);
                pRoot = pRoot.left;
            }
            else {//找到最左,出栈
                pRoot = stack.remove(stack.size()-1);
                count++;
                if(count==k) return pRoot;
                pRoot = pRoot.right;
            }
        }
         
        return null;
    }
 
}

 

public class Solution {
    private ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        ArrayList<Integer> list = new ArrayList<>();
        recur(root, sum, list);
        return lists;
    }
    public void recur(TreeNode root, int sum, ArrayList<Integer> list) {
        if (root == nullreturn;
        list.add(root.val); // 先加入list中
        if (root.left == null && root.right == null) { // 到达叶子结点
            if (sum == root.val) lists.add(new ArrayList<Integer>(list));
            list.remove(list.size()-1); // 移除当前结点
        else {
            recur(root.left, sum - root.val, list);
            recur(root.right, sum - root.val, list);
            list.remove(list.size()-1); // 递归返回时移除上一个结点
        }
    }
}
posted @ 2021-08-12 21:31  哥们要飞  阅读(44)  评论(0编辑  收藏  举报