Binary Tree练习二叉树遍历递归257、100、222、101、226、437、563、617、572、543、|687

257. 二叉树的所有路径

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

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

1
/
2 3

5

输出: [“1->2->5”, “1->3”]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
题解:
1)dfs
2)bfs 队列判断是不是叶子节点,不是放队尾,是添加到路径直到队伍空
solution:

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res=new ArrayList<>();
        if(root==null) return res;
        dfs(root,"",res);
        return res;
    }
    public void dfs(TreeNode root,String cur,List<String> res){
        if(root==null) return;
        cur+=root.val;
        if(root.left==null&&root.right==null) res.add(cur);
        else {
         dfs(root.left,cur+"->",res);
         dfs(root.right,cur+"->",res);
    }
    }
}

543. 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
题解:递归 遍历每一个结点,计算最长路径(左子树边长+右子树边长),更新全局变量max。

class Solution {
    int max = 0;
    public int diameterOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        dfs(root);
        return max;
    }
    
    private int dfs(TreeNode root) {
        if (root.left == null && root.right == null) {
            return 0;
        }
        int leftSize = root.left == null? 0: dfs(root.left) + 1;
        int rightSize = root.right == null? 0: dfs(root.right) + 1;
        max = Math.max(max, leftSize + rightSize);
        return Math.max(leftSize, rightSize);
    }  
}

563. 二叉树的坡度

给定一个二叉树,计算整个树的坡度。
一个树的节点的坡度定义即为,该节点左子树的结点之和和右子树结点之和的差的绝对值。空结点的的坡度是0。
整个树的坡度就是其所有节点的坡度之和,
题解:
1)递归
整个树的坡度就是其所有节点的坡度之和,递归计算每个节点的坡度。即求每个节点的左子树坡度和 与 右子树坡度和;
子树的坡度和 = 子树根节点值 + 子树左子树坡度和 + 子树右子树坡度之和;继续分解,直到分解到空树,空树的坡度为0,为递归出口。
sloution:
1)java Math.abs()方法求绝对值

class Solution {
    public int findTilt(TreeNode root) {
    if(root==null) return 0;
    return Math.abs(s(root.left)-s(root.right)) +findTilt(root.left)+findTilt(root.right);
    }
    private int s(TreeNode root){
    if(root == null) return 0;    
    return root.val + s(root.right) +s(root.left);
    }
}

617. 合并二叉树

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

题解:
递归:前序遍历的应用
sloution:

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) {
            return null;}
    TreeNode root = new TreeNode((t1 == null ? 0 : t1.val) + (t2 == null ? 0 : t2.val));
    root.left = mergeTrees(t1 == null ? null : t1.left, t2 == null ? null : t2.left);
    root.right = mergeTrees(t1 == null ? null : t1.right, t2 == null ? null : t2.right);
    return root;
}
}

226. /27.翻转二叉树

题解:
1)递归
2)迭代:队列。只要这个队列不空,就一直从队列中出队节点,然后互换这个节点的左右孩子节点,接着再把孩子节点入队到队列,最后返回根节点
sloution:
1)递归 c++

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) {
            return NULL;
        }
        swap(root->left, root->right);
        invertTree(root->left);
       invertTree(root->right);
        return root;
    }
};

2)迭代 官方java

public TreeNode invertTree(TreeNode root) {
    if (root == null) return null;
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    while (!queue.isEmpty()) {
        TreeNode current = queue.poll();
        TreeNode temp = current.left;
        current.left = current.right;
        current.right = temp;
        if (current.left != null) queue.add(current.left);
        if (current.right != null) queue.add(current.right);
    }
    return root;
}

101. 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。
题解:
1)递归 复杂度O(n)
2)迭代:引入队列,递归改写成迭代的常用方法。
每次pop两个结点比较值,再将两个结点的左右子结点按相反的顺序插入队列中。
sloution:
1)递归 java

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return cmp(root,root);
    }
    private boolean cmp(TreeNode t1,TreeNode t2){
        if(t1==null && t2==null) return true;
        if(t1==null || t2==null) return false;
        if(t1.val!=t2.val) return false;
        return cmp(t1.left,t2.right) && cmp(t1.right,t2.left);
    }
}

2)迭代 c++官方题解:

class Solution {
public:
    bool check(TreeNode *u, TreeNode *v) {
        queue <TreeNode*> q;
        q.push(u); q.push(v);
        while (!q.empty()) {
            u = q.front(); q.pop();
            v = q.front(); q.pop();
            if (!u && !v) continue;
            if ((!u || !v) || (u->val != v->val)) return false;

            q.push(u->left); 
            q.push(v->right);

            q.push(u->right); 
            q.push(v->left);
        }
        return true;
    }

    bool isSymmetric(TreeNode* root) {
        return check(root, root);
    }
};

222. 完全二叉树的节点个数

给出一个完全二叉树,求出该树的节点个数。
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
即:一棵空树或者它的叶子节点只出在最后两层,若最后一层不满则叶子节点只在最左侧。
题解:
1)java递归 ->没有用到完全二叉树的性质

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

2)定义左子树层高left,右子树层高right。
若相等,左子树是满二叉树,左子树的节点总数是2^left -1,加上当前这个root节点,则是2^left ,再对右子树进行递归统计。
否则右子树是满二叉树,右子树节点+root节点,总数为2^right。再对左子树进行递归查找。
注:位运算 左移相当于*2

class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int left = countLevel(root.left);
        int right = countLevel(root.right);
        if (left == right) {
            return countNodes(root.right) + (1 << left);
        } else {
            return countNodes(root.left) + (1 << right);
        }
    }
//计算层数
    private int countLevel(TreeNode root) {
        int level = 0;
        while (root != null) {
            level++;
            root = root.left;
        }
        return level;
    }
}

100. 相同的树

给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

题解:
递归 需要判断的三种
1、都为空、相同
2、一个空、一个非空,不同
3、都不为空但val不同

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

572. 另一个树的子树

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

sloution:

class Solution {
    public boolean isSubtree(TreeNode s, TreeNode t) {
    if (t==null) return true;
    if (s==null) return false;
    return isSubtree(s.right,t) || isSubtree(s.left,t) || isSameTree(s,t);
    }

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

404.二叉搜索树的第k大节点

给定一棵二叉搜索树,找出其中第k大的节点。

题解:
1)中序遍历得到的序列是有序的(递增)
2)由题第k大则为中序遍历倒序:右根左 第k小:左根右

sloution:
1)中序遍历用ArrayList记录

class Solution {
    public int kthLargest(TreeNode root, int k) {
        List<Integer> list = new ArrayList<>();
        helper(root, list);
        return list.get(list.size() - k);
    }
    
    private void helper(TreeNode root, List<Integer> list) {
        if (root == null) return;
        if (root.left != null) helper(root.left, list);
        list.add(root.val);
        if (root.right != null) helper(root.right, list);
    }
}

2)递归优化:遍历到第k大就停止

class Solution {
    private int ans = 0, cnt = 0;
    public int kthLargest(TreeNode root, int k) {
        dfs(root, k);
        return ans;
    }
    private void dfs(TreeNode root, int k) {
        if(root == null) return ;
        dfs(root.right, k);
        if(++cnt == k) {
            ans = root.val;
        }
        dfs(root.left, k);
    }
}

3)迭代:利用栈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值