二叉树题目合集

104. Maximum Depth of Binary Tree

找到二叉树的最大深度。

public class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int l = maxDepth(root.left) + 1;
        int r = maxDepth(root.right) + 1;
        return l > r ? l : r;
    }
}

111. Minimum Depth of Binary Tree

找到二叉树的最小深度

思路:与最大深度不同的地方在于,若一个节点只有左节点或者右节点的其中之一的节点,则该节点并不为完整路径的叶节点,一定要找到叶节点才能判断最小路径

public class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null) {
            return minDepth(root.right) + 1;
        }
        if (root.right == null) {
            return minDepth(root.left) + 1;
        }
        return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
    }
}

112. Path Sum

给定一个树和一个整数,决定是否该树有从跟节点到叶节点的一条路径上的值的和等于给定的这个整数

思路:前序遍历,若没有左右子节点的话,判断当前根节点是否等于sum,若不等于,sum减去当前根节点的值,继续向下遍历。

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

113. Path Sum II

给定一个树和一个整数,找到所有从根节点到叶节点的路径上的值的和等于给的这个整数,要返回下面这种。

[
   [5,4,11,2],
   [5,8,4,5]
]

思路:与上一题不同之处在于,上一题是判断存不存在,该题要找到所有符合的路径,两个list是必不可少。内层list来存储符合的路径。然后遍历到叶节点符合条件,就将对应的一条路径添加到外层list中,这里有两个关键点,前序遍历是必不可少,问题是遍历的过程中如果访问到某一叶节点,但这条路径不符合。那么内层list需要一个一个remove掉当前元素,即使该路径符合,为了寻找新的符合条件路径,也需要remove掉当前的值。所以在遍历的最后要remove掉当前节点的值。

易错的地方:因为innerlist是处于一直增删的状态。所以确定了某一完整的符合条件的路径后,应新建一个temp的list来存储对应的innerlist,但不能直接把引用=innerlist,这样两者的地址会一样。所以方法是将innerlist的值复制到temp中,所以应该用 addAll方法来处理。

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

        if (root.left == null && root.right == null && sum == 0) {
            List<Integer> temp = new ArrayList<>();
            temp.addAll(innerlist);
            list.add(temp);

        }
        if (root.left != null) {
            innerlist.add(root.left.val);
            hasPathSum(root.left, sum - root.left.val);
            innerlist.remove(innerlist.size() - 1);
        }
        if (root.right != null) {
            innerlist.add(root.right.val);
            hasPathSum(root.right, sum - root.right.val);
            innerlist.remove(innerlist.size() - 1);
        }
    }
}

437. Path Sum III

给定一个树和一个整数,找到所有从任意节点到任意节点的路径上的值的和等于给的这个整数,但一定是从上到下的逻辑顺序。返回共有多少条路径。

思路:与前两题不一样的地方在于 不是从根节点开始了,而是从任意节点开始到下面节点路径和为该值即可。很典型的动态规划的问题。先考虑跟节点去往下遍历,记录从根节点开始的符合情况,接着从根节点的左右子节点开始遍历。

public class Solution {
    public int pathSum(TreeNode root, int sum) {
        if (root == null) {
            return 0;
        }
        return dfs(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
    }
    public int dfs(TreeNode root, int sum) {
        int res = 0;
        if (root == null) {
            return 0;
        }
        if (root.val == sum) {
            ++res;
        }
        res += dfs(root.left, sum - root.val);
        res += dfs(root.right, sum - root.val);
        return res;
    }
}

102. Binary Tree Level Order Traversal    待修改,减少空间复杂度

给定一个二叉树,从左到右,一层一层返回遍历的值。类似下面这种

    3
   /   9  20
    /     15   7

return its level order traversal as:

[
  [3],
  [9,20],
  [15,7]
]

思路:利用两个双端队列linkedlist去存储当前遍历的层以及下一层要遍历的元素,通过remove将队列中的节点一个一个处理。
public class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<List<Integer>>();
        ArrayList<Integer> nodeValue = new ArrayList<Integer>();
        if (root == null){
            return list;
        }
        LinkedList<TreeNode> current = new LinkedList<TreeNode>();
        LinkedList<TreeNode>  next = new LinkedList<TreeNode>();
        current.add(root);
        while (!current.isEmpty()) {
            TreeNode node = current.remove();
            if (node.left != null) {
                next.add(node.left);
            }
            if (node.right != null) {
                next.add(node.right);
            }
            nodeValue.add(node.val);
            if (current.isEmpty()) {
                current = next;
                next = new LinkedList<TreeNode>();
                list.add(nodeValue);
                nodeValue = new ArrayList<Integer>();
            }
        }
        return list;
    }
}

107. Binary Tree Level Order Traversal II   待修改,减少空间复杂度

与上题不同之处在于要倒序输出,返回如下这种

[
  [15,7],
  [9,20],
  [3]
]思路:最后对上一题的list进行reverse即可。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> list = new ArrayList<List<Integer>>();
        List<Integer> nodeValue = new ArrayList<Integer>();
        if (root == null){
            return list;
        }
        LinkedList<TreeNode> current = new LinkedList<TreeNode>();
        LinkedList<TreeNode> next = new LinkedList<TreeNode>();
        current.add(root);
        while (!current.isEmpty()){
            TreeNode node = current.remove();
            if (node.left != null){
                next.add(node.left);
            }
            if (node.right != null){
                next.add(node.right);
            }
            nodeValue.add(node.val);
            if (current.isEmpty()){
                current = next;
                next = new LinkedList<TreeNode>();
                list.add(nodeValue);
                nodeValue = new ArrayList<Integer>();
            }
        }
        Collections.reverse(list);return reverseList;
    }
}

100. Same Tree

给两个二叉树,判断这个两个二叉树是不是相同的,如果他们结构一致,且节点值相同,则为相同

思路:该题不难,遍历对应的节点值是否相等即可。



public class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if (p == null || q == null) {
            return false;
        }
        if (p.val != q.val) {
            return false;
        }
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

 
时间: 2024-11-07 22:35:33

二叉树题目合集的相关文章

二分图的一些题目合集

妈蛋状态都被狗吃了,已经开始不自觉对着电脑发呆……被几道二分图的题亮瞎了双眼(这么弱可是gdkoi只剩一个月gdoi只剩100+天……!!) wikioi1222信与信封问题 二分图,但是判断两个合集中的某两个点是不是只能连在一起.那么我们就在跑一边最大匹配后直接用是否可以增广来判断.如果可以增广那么这两个点是有其他方式连在一起的,否则这两个点就必须连在一起.具体做法是先去掉这两个点的边,不过那么match数组也要跟着改一下. var map:array[0..200,0..200]of boo

array题目合集

283. Move Zeroes 给定任意一个数组,把其中的0都移到该数组的末尾,其他的数字相对顺序要保持不变.例如:nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. 思路:不是0的往前赋值,同时用一个下标纪录当前赋值的数量,最后从这个下标开始赋值0即可. public class MoveZeroes { public void moveZeroes(int[] nums

最长上升子序列(LIS)题目合集

有关最长上升子序列的详细算法解释在http://www.cnblogs.com/denghaiquan/p/6679952.html 1)51nod 1134 一题裸的最长上升子序列,由于N<=50000,n2算法会超时,只能用nlogn算法. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string

sizeof题目合集

32位机器上定义如下结构体: struct xx{    long long _x1;    char _x2;    int _x3;    char _x4[2];    static int _x5;};int xx::_x5; 1-8的地址分给了_x1 , 9分给了_x2, 13-16分给了_x3,  int要按4对齐所以10-13的空间其实是浪费了 17-18分给了_x4, _x5不占用空类间, 最后本身是需要按照8对其 所以19-24也被占用了

openjudge1.6 题目合集(08~15)

08-石头剪刀布 #include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[10001]; int b[10001]; int now_a[100001]; int now_b[100001]; int ying_a; int ying_b; int ping; int m

函数易错题目合集

var f1 = function f2(){}; f1.name //"f2" var f1 = function f2(){}; f2.name //报错:f2 is not defined var f1 = function f2(){}: console.log(f2) //f2 is not defined(f2 不存在,而且 f2 不是 undefined) function f(){console.log(this)}: f.call(1) //Number 对象 1 f

《github一天一道算法题》:搜索二叉树接口实现大合集

读书.思考.写代码! 说明: (1)这里实现了搜索二叉树的全部常用操作 (2)限于时间和精力,实现的较为粗糙,内存泄露.成员变量访问控制.返回类型.异常安全等没有照顾的到 (3)一切实现的手段都是贴近底层操作,关注原理.以后可能对推倒重来,实现一个完备的接口系统. /********************************************* * [email protected] * 题目:二叉树接口实现大合集 * 具体:二叉树的创建.插入.最大值.最小值.前中后序递归遍历与非递

[知识点]NOIP动态规划大合集

1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NOIP2003 加分二叉树 树形DP入门题,根据题意,一个树的加分=左子树*右子树+根节点,由此可以设f[i][j]为子树i到j的加分,则有方程:f[i][j]=max{d[t]+f[i,t-1]*f[t+1,j]} ( t∈[i,j] ) 3.NOIP2004 合唱队形 应该是最简单的一道了,枚举队

[题解+总结]动态规划大合集II

1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2.lis 最长上升子序列 唯一一道裸题,但是O(n^2)过不了,临时看了看O(n log n)的二分做法和线段树做法.先来讲讲简单的二分做法,其本质就是在O(n^2)上进行优化,需要证明一个结论.设当前处理数列第k位,存在: (1)a[i]<a[j]<a[k]: (2)i<j<k: (3