LeetCode算法题--二叉树

0100 相同的树

题目:判断两棵树是否一样(节点值与树的结构都需要相同)

//100
public static boolean isSameTree(TreeNode p, TreeNode q) {
    if (p==null&&q==null){
        return true;
    }
    if (p==null&&q!=null){
        return false;
    }
    if (p!=null&&q==null){
        return false;
    }
    if (p.val==q.val){
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }else{
        return false;
    }
}

0101 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

//101
public boolean isSymmetric(TreeNode root) {
    if (root==null){
        return true;
    }
    return isMirror(root.left,root.right);
}

public static boolean isMirror(TreeNode r1, TreeNode r2){
    if (r1==null&&r2==null){
        return true;
    }
    if (r1==null||r2==null){
        return false;
    }
    if (r1.val==r2.val){
        return isMirror(r1.left,r2.right)&&isMirror(r1.right,r2.left);
    }else{
        return false;
    }
}

0107 二叉树层序遍历

题目:输出每一层的值

思路:广度优先搜索,板子题。

static LinkedList<List<Integer>>levelList;
public static List<List<Integer>> levelOrderBottom(TreeNode root) {
    levelList= new LinkedList<>();
    if (root==null){
        return levelList;
    }
    Queue<TreeNode> q= new LinkedList<>();
    q.add(root);
    while(!q.isEmpty()){
        List <Integer>list = new LinkedList<>();
        int size= q.size();
        for (int i = 0; i < size ; i++) {
            TreeNode t=q.poll();
            list.add(t.val);
            if (t.left!=null){
                q.add(t.left);
            }
            if (t.right!=null){
                q.add(t.right);
            }
        }
        levelList.addFirst(list);
    }
    return levelList;
}

0111 二叉树最小深度

给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

//111
public static int minDepth(TreeNode root) {
    if (root==null){
        return 0;
    }
    if (root.left==null&&root.right==null){
        return 1;
    }
    if (root.left==null){
        return 1+minDepth(root.right);
    }
    if (root.right==null){
        return 1+minDepth(root.left);
    }
    return 1+Math.min(minDepth(root.left),minDepth(root.right));
}

0112 路径总和

题目:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

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);
}

0226 翻转二叉树

题目:将节点的所有左右节点互换。

public static TreeNode invertTree(TreeNode root) {
    if (root==null){
        return root;
    }
    if (root.left==null&&root.right==null){
        return root;
    }
    if (root.left==null){
        root.left=root.right;
        root.right=null;
    }else if (root.right==null){
        root.right=root.left;
        root.left=null;
    }
    if (root.left!=null&&root.right!=null){
        TreeNode t= root.left;
        root.left=root.right;
        root.right=t;
    }
    invertTree(root.left);
    invertTree(root.right);
    return root;
}

0235 二叉搜索树的公共祖先

**公共祖先:**对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u和v的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先。

public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    int rootVal= root.val;
    int pVal=p.val;
    int qVal=q.val;
    if (p.val<root.val&&q.val<root.val){
        return lowestCommonAncestor(root.left,p,q);
    }else if (p.val>root.val&&q.val>root.val){
        return lowestCommonAncestor(root.right,p,q);
    }else{
        return root;
    }
}

0257 二叉树的所有路径

**题目:**给定一个二叉树,返回所有从根节点到叶子节点的路径。

注意:path是字符串类型,作为参数传递给construct_paths方法,是传递地址的拷贝。

public static List<String> binaryTreePaths(TreeNode root) {
    LinkedList<String> paths = new LinkedList();
    constructPath(root, "", paths);
    return paths;
}

public static void constructPath
    (TreeNode root, String path, List<String> paths){
    if (root!=null){
        path += Integer.toString(root.val);
        if (root.left==null&&root.right==null){
            paths.add(path);
        }else{
            path+="->";
            constructPath(root.left,path,paths);
            constructPath(root.right,path,paths);
        }
    }
}



//强行回溯,用list。有很多改进方案
static LinkedList<LinkedList<Integer>>pathList;
public static List<String> binaryTreePaths(TreeNode root) {
    pathList= new LinkedList<>();
    List<String>answer= new LinkedList<>();
    if (root==null){
        return answer;
    }
    backtrace(root,new LinkedList<>());
    for (int i = 0; i < pathList.size() ; i++) {
        LinkedList<Integer>temp= pathList.get(i);
        String ans= new String();
        //            System.out.println(temp.size());
        for (int j = 0; j < temp.size() ; j++) {
            if (j==0){
                ans+=Integer.toString(temp.get(j));
            }else{
                ans+="->"+Integer.toString(temp.get(j));
            }
        }
        answer.add(ans);
    }
    return answer;
}

public static void backtrace(TreeNode root, LinkedList<Integer>list){
    if (root.left==null&&root.right==null){
        list.add(root.val);
        pathList.add(new LinkedList<>(list));
        list.removeLast();
        return;
    }
    list.add(root.val);
    if (root.left!=null) {
        backtrace(root.left, list);
    }
    if (root.right!=null) {
        backtrace(root.right, list);
    }
    list.removeLast();
}

0404 左叶子之和

题目:求树的所有左叶子节点

//404
public static int sumOfLeftLeaves(TreeNode root) {
    if (root==null){
        return 0;
    }
    if (root.left==null){
        return sumOfLeftLeaves(root.right);
    }
    if (root.left.left==null&&root.left.right==null){
        return root.left.val+sumOfLeftLeaves(root.right);
    }
    return sumOfLeftLeaves(root.left)+sumOfLeftLeaves(root.right);
}

0437 路径总和

给定一个二叉树,它的每个结点都存放着一个整数值。找出路径和等于给定数值的路径总数。

public static int pathSum(TreeNode root, int sum) {
    if (root==null){
        return 0;
    }
    return Sum(root,sum)+pathSum(root.left,sum)+pathSum(root.right,sum);
}

public static int Sum(TreeNode root, int sum){
    if(root==null){
        return 0;
    }
    sum-=root.val;
    if (sum==0){
        return 1+Sum(root.left,sum)+Sum(root.right,sum);
    }
    return Sum(root.left,sum)+Sum(root.right,sum);
}

0501 二叉搜索树中的众数

题目:求BST的众数

思路:中序遍历BST为递增序列,转化为求递增序列的众数。

List<Integer>list= new ArrayList<>();
int preval=0; int currtimes=0; int maxtimes=0;

public int[] findMode(TreeNode root) {
    inorder(root);
    int ans[] = new int[list.size()];
    for (int i = 0; i < list.size() ; i++) {
        ans[i]=list.get(i);
    }
    return ans;
}

public void inorder(TreeNode root){
    if(root != null){
        inorder(root.left);
        if (root.val==preval){
            currtimes++;
        }else{
            preval=root.val;
            currtimes=1;
        }
        if (currtimes==maxtimes){
            list.add(root.val);
        }
        if (currtimes>maxtimes){
            maxtimes=currtimes;
            list.clear();
            list.add(preval);
        }
        inorder(root.right);
    }
}

0538 把二叉搜索树转换为累加树

题目:给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。

思路:反序遍历就是降序,一次遍历即可

int count=0;
public TreeNode convertBST(TreeNode root) {
    reverseOrder(root);
    return root;
}

public void reverseOrder(TreeNode root){
    if (root!=null){
        reverseOrder(root.right);
        count+=root.val;
        root.val=count;
        reverseOrder(root.left);
    }
}

0543 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

int ans=0;
public int diameterOfBinaryTree(TreeNode root) {
    if (root==null){
        return 0;
    }
    depth(root);
    return ans;
}

    
public int depth(TreeNode node) {
    if (node == null) return 0;
    int L = depth(node.left);
    int R = depth(node.right);
    ans = Math.max(ans, L+R);//直径
    return Math.max(L, R) + 1;//深度
}


//更加清晰的思路,左右最大深度之和为直径。但是时间复杂度爆炸,只为解释一下上面解法
int ans=0;
public int diameterOfBinaryTree(TreeNode root) {
    if (root == null) {
        return 0;
    }
    preorder(root);
    return ans;
}
public void preorder(TreeNode root){
    if (root!=null){
        preorder(root.left);
        int L= maxdepth(root.left);
        int R= maxdepth(root.right);
        ans=Math.max(ans,L+R);
        preorder(root.right);
    }
}

public int maxdepth (TreeNode root){
    if (root==null){
        return 0;
    }
    return 1+Math.max(maxdepth(root.left),maxdepth(root.right));
}

0563 二叉树的坡度

题目:一个树的节点的坡度定义即为,该节点左子树的结点之和和右子树结点之和的差的绝对值。空结点的的坡度是0。

思路:想到后序遍历,存储左子树的结点之和和右子树结点和,再计算

//法一
int tilt=0;
public int findTilt(TreeNode root) {
    traverse(root);
    return tilt;
}
public int traverse(TreeNode root)
{
    if(root==null )
        return 0;
    int left=traverse(root.left);
    int right=traverse(root.right);
    tilt+=Math.abs(left-right);
    return left+right+root.val;
}

//法二
/*两次遍历*/
int answer=0;
public int findTilt(TreeNode root) {
    if (root==null){
        return 0;
    }
    backorder(root);
    backorderMinus(root);
    return answer;
}

public void  backorderMinus(TreeNode root){
    if(root != null){
        backorderMinus(root.left);
        backorderMinus(root.right);
        if (root.left==null&&root.right!=null){
            answer+=Math.abs(root.right.val);
        }else if (root.left!=null&&root.right==null){
            answer+=Math.abs(root.left.val);
        }else if (root.left!=null&&root.right!=null){
            answer+=Math.abs(root.left.val-root.right.val);
        }
    }
}

public void  backorder(TreeNode root){
    if(root != null){
        backorder(root.left);
        backorder(root.right);
        if (root.left==null&&root.right!=null){
            root.val+=root.right.val;
        }else if (root.left!=null&&root.right==null){
            root.val+=root.left.val;
        }else if (root.left!=null&&root.right!=null){
            root.val+=root.left.val+root.right.val;
        }
    }
}

0572 另一个树的子树

题目:给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

思路:如果s和t的val相等,判断是否为sameTree;如果不等,再判断s的左右子树

public static boolean isSameTree(TreeNode p, TreeNode q) {
    if (p==null&&q==null){
        return true;
    }
    if (p==null&&q!=null){
        return false;
    }
    if (p!=null&&q==null){
        return false;
    }
    if (p.val==q.val){
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }else{
        return false;
    }
}
public boolean isSubtree(TreeNode s, TreeNode t) {
    if (t==null){
        return true;
    }
    if (s==null){
        return false;
    }
    if (s.val!=t.val){
        return isSubtree(s.left,t)||isSubtree(s.right,t);
    }else{
        return isSameTree(s,t)||isSubtree(s.left,t)||isSubtree(s.right,t);
    }
}

0617 合并二叉树

题目:给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

思路:以t1为主体,递归建树

public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
    if (t1==null){
        return t2;
    }
    if (t2==null){
        return t1;
    }
    t1.val=t1.val+t2.val;
    t1.left = mergeTrees(t1.left, t2.left);
    t1.right = mergeTrees(t1.right, t2.right);
    return t1;
}

0637 二叉树的层平均值

题目:给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.

思路:层序遍历,BFS,与0107类似。

public List<Double> averageOfLevels(TreeNode root) {
    List<Double>list= new LinkedList<>();
    if (root==null){
        return list;
    }
    Queue<TreeNode>q= new LinkedList<>();
    q.add(root);
    while(!q.isEmpty()){
        double sum=0;
        int size= q.size();
        for (int i = 0; i < size; i++) {
            TreeNode t = q.poll();
            sum+=t.val;   
            if (t.left!=null){
                q.add(t.left);
            }
            if (t.right!=null){
                q.add(t.right);
            }
        }
        list.add(sum/size);
    }
    return list;
}

0108 将有序数组转化为BST

思路:二分查找,递归建树

public TreeNode sortedArrayToBST(int[] nums) {
    // 左右等分建立左右子树,中间节点作为子树根节点,递归该过程
    return nums == null ? null : buildTree(nums, 0, nums.length - 1);
}

private TreeNode buildTree(int[] nums, int l, int r) {
    if (l > r) {
        return null;
    }
    int m = l + (r - l) / 2;
    TreeNode root = new TreeNode(nums[m]);
    root.left = buildTree(nums, l, m - 1);
    root.right = buildTree(nums, m + 1, r);
    return root;
}
原创文章 14 获赞 10 访问量 583

猜你喜欢

转载自blog.csdn.net/qq_43672466/article/details/104947666