二叉树算法题总结

129. 求根到叶子节点数字之和

在这里插入图片描述
方法1:广度优先搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int sumNumbers(TreeNode root) {
        return bfs(root);
    }

    public int bfs(TreeNode root){
        if(root==null) return 0;
        Queue<TreeNode> qu=new LinkedList<TreeNode>();
        Queue<Integer> quNum=new LinkedList<Integer>();
        int sum=0;
        qu.offer(root);
        quNum.offer(root.val);
        while(!qu.isEmpty()){
            TreeNode p=qu.poll();
            int num=quNum.poll();
            if(p.left==null&&p.right==null){
                sum+=num;
            }
            if(p.left!=null){
                qu.offer(p.left);
                quNum.offer(num*10+p.left.val);
            }
            if(p.right!=null){
                qu.offer(p.right);
                quNum.offer(num*10+p.right.val);
            }
        }
        return sum;
    }
}

方法2:深度优先搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int sumNumbers(TreeNode root) {
        //假设根节点的父节点值为0
        return dfs(root,0);
    }

    public int dfs(TreeNode root,int preNode){
        if(root==null) return 0;
        int sum=preNode*10+root.val;
        if(root.left==null&&root.right==null){
            return sum;
        }else{
            return dfs(root.left,sum)+dfs(root.right,sum);
        }
    }
}

863. 二叉树中所有距离为 K 的结点

在这里插入图片描述
方法1:深度优先搜索
先利用深度优先遍历找到每个结点的父节点,再利用深度优先遍历查找结点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
        List<Integer> list=new ArrayList<>();
        Map<TreeNode,TreeNode> parentMap=new HashMap<>();
        searchParent(root,parentMap);
        boolean [] visited=new boolean[501];
        dfs(target,K,parentMap,visited,list);
        return list;
    }
    //找到每个结点的父节点
    public void searchParent(TreeNode root,Map<TreeNode,TreeNode> parentMap){
        if(root==null) return;
        if(root.left!=null){
            parentMap.put(root.left,root);
        }
        if(root.right!=null){
            parentMap.put(root.right,root);
        }
        searchParent(root.left,parentMap);
        searchParent(root.right,parentMap);
    }
    //深度优先遍历
    public void dfs(TreeNode target,int k,Map<TreeNode,TreeNode> parentMap,boolean[] visited,List<Integer> list){
        if(target == null || k < 0 || visited[target.val]) return;
        if(k==0 && !visited[target.val]){
            list.add(target.val);
            visited[target.val]=true;
            return;
        }
        visited[target.val]=true;
        dfs(target.left,k-1,parentMap,visited,list);
        dfs(target.right,k-1,parentMap,visited,list);
        dfs(parentMap.get(target),k-1,parentMap,visited,list);
        
    } 

}

方法2:计算结点之间的距离(待定)

剑指 Offer 34. 二叉树中和为某一值的路径

在这里插入图片描述
方法1:先序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<List<Integer>> lists=new LinkedList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        dfs(root,sum);
        return lists;
    }

    //先序遍历
    public void dfs(TreeNode root,int sum){
        if(root==null) return;
        path.add(root.val);
        sum-=root.val;
        if(sum==0&&root.left==null&&root.right==null) {
            lists.add(new LinkedList(path));
        }
        dfs(root.left,sum);
        dfs(root.right,sum);
        path.removeLast();
    }
}

剑指 Offer 32 - III. 从上到下打印二叉树 III

在这里插入图片描述
方法1:借助广度优先搜索,每次打印两层,先打印奇数层,再打印偶数层,如果没有偶数层,则结束循环。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root==null) return new ArrayList<>();
        List<List<Integer>> lists=new ArrayList<>();//二维数组存放输出数据
        Deque<TreeNode> qu=new LinkedList<>();//借助LinkedList实现双端队列
        qu.offer(root);
        //每次循环打印两层
        while(!qu.isEmpty()){
            LinkedList<Integer> list=new LinkedList<>();
            
            //先打印奇数层
            for(int i=qu.size();i>0;i--){
                TreeNode q=qu.removeFirst();
                list.add(q.val);
                if(q.left!=null) qu.addLast(q.left);
                if(q.right!=null) qu.addLast(q.right);
            }
            lists.add(list);

            //若没有偶数层了,就退出循环
            if(qu.isEmpty()) break;

            //再打印偶数层
            list=new LinkedList<>();
            for(int i=qu.size();i>0;i--){
                TreeNode q=qu.removeLast();
                list.add(q.val);
                if(q.right!=null) qu.addFirst(q.right);
                if(q.left!=null) qu.addFirst(q.left);
            }
            lists.add(list);
        }
        return lists;
    }

}

方法2:利用二维数组的行数判断层数,每次打印一层。

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) queue.add(root);
        while(!queue.isEmpty()) {
            LinkedList<Integer> tmp = new LinkedList<>();
            for(int i = queue.size(); i > 0; i--) {
                TreeNode node = queue.poll();
                if(res.size() % 2 == 0) tmp.addLast(node.val); // 偶数层 -> 队列头部
                else tmp.addFirst(node.val); // 奇数层 -> 队列尾部
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
    }
}

匹配类二叉树题目总结:剑指 Offer 26. 树的子结构、1367. 二叉树中的列表、101. 对称二叉树、572. 另一个树的子树

剑指 Offer 26. 树的子结构

在这里插入图片描述
方法:递归的方式实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        return (A!=null&&B!=null)&&(judge(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B));
    }

    public boolean judge(TreeNode A,TreeNode B){
        if(B==null) return true;
        if(A==null||A.val!=B.val) return false;
        return judge(A.left,B.left)&&judge(A.right,B.right);
    }
}

1367. 二叉树中的列表

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSubPath(ListNode head, TreeNode root) {
        if(root==null) return false;
        return dfs(head,root)||isSubPath(head,root.left)||isSubPath(head,root.right);
    }

    public boolean dfs(ListNode head,TreeNode root){
        if(head==null) return true;
        if(root==null||head.val!=root.val) return false;
        return dfs(head.next,root.left)||dfs(head.next,root.right);
    }
}

572. 另一个树的子树

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSubtree(TreeNode s, TreeNode t) {
        if(s==null) return false;
        return dfs(s,t)||isSubtree(s.left,t)||isSubtree(s.right,t); 
    }

    public boolean dfs(TreeNode s,TreeNode t){
        if(t==null&&s==null) return true;
        if(t==null||s==null||s.val!=t.val) return false;
        return dfs(s.left,t.left)&&dfs(s.right,t.right);
    }
}

剑指 Offer 07. 重建二叉树

在这里插入图片描述
方法:递归实现。使用一个 Map 存储中序遍历的每个元素及其对应的下标,目的是为了快速获得一个元素在中序遍历中的位置。调用递归方法,对于前序遍历和中序遍历,下标范围都是从 0 到 n-1,其中 n 是二叉树节点个数。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int[] preorder;
    Map<Integer,Integer> treeMap=new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder=preorder;
        int n=preorder.length;
        if(n==0) return null;
        for(int i=0;i<n;i++){
            treeMap.put(inorder[i],i);
        }
        return build(0,0,n-1);
    }

    public TreeNode build(int root,int left,int right){
        if(left>right) return null;
        TreeNode node=new TreeNode(preorder[root]);
        int i=treeMap.get(preorder[root]);
        node.left=build(root+1,left,i-1);
        node.right=build(root-left+i+1,i+1,right);
        return node;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值