Leetcode面T4(1-9)树(1)

while (!queue.isEmpty()) {

//当前队列的长度,即当前层元素的总个数

int size = queue.size();

//链表的头结点,不放实际的值(哑元)

ListNode head = new ListNode(0);

//链表移动指针,让它始终指向当表链表的最后一个元素

ListNode p = head;

//将当前层的节点逐个出队,把出队节点的子节点入队

for (int i = 0; i < size; i++) {

TreeNode poll = queue.poll();

//链表元素追加

p.next = new ListNode(poll.val);

//指针向后移动一个元素,使p指向链表末尾

p = p.next;

if (poll.left != null) {

//当前出队的节点有左孩子,则左孩子入队

queue.add(poll.left);

}

if (poll.right != null) {

//当前出队的节点有右孩子,则右孩子入队

queue.add(poll.right);

}

}

//for循环走完后就遍历完了一层,将存储该层节点的链表第一个有实际值的节点入队

list.add(head.next);

}

//将可变长的数组转化成定长数组(因为函数的返回值要求了返回一个定长数组ListNode[])

return list.toArray(new ListNode[list.size()]);

}

}

Q4.4  检查平衡性

实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个节点,其两棵子树的高度差不超过 1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

3

/ \

9  20

/  \

15   7

返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

1

/ \

2   2

/ \

3   3

/ \

4   4

返回 false 。

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }

*/

class Solution {

public boolean isBalanced(TreeNode root) {

if(root==null) return true;

int x=depth(root.left);

int y=depth(root.right);

if(x-y>=-1&&x-y<=1){

boolean m=isBalanced(root.left);

boolean n=isBalanced(root.right);

return m&&n;

}else{

return false;

}

}

public int depth(TreeNode root){

if(root==null) return 0;

return Math.max(depth(root.left),depth(root.right))+1;

}

}

Q4.5  合法二叉搜索树

实现一个函数,检查一棵二叉树是否为二叉搜索树。

示例 1:

输入:

2

/ \

1   3

输出: true

示例 2:

输入:

5

/ \

1   4

/ \

3   6

输出: false

解释: 输入为: [5,1,4,null,null,3,6]。

根节点的值为 5 ,但是其右子节点值为 4 。

二叉搜索树的定义如下

  • 一个节点的左子树上节点的值都小于自身的节点值

  • 一个节点的右子树上节点的值都小于自身的节点值

  • 所有节点的左右子树都必须是二叉搜索树

采用递归中序遍历方法依次比较当前节点值和后一个节点值的大小,若当前节点值大于等于后一个节点值,则不是 二叉搜索树:

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }

*/

class Solution {

Integer pre = null;

public boolean isValidBST(TreeNode root) {

if (root == null) return true;

if (isValidBST(root.left)) {

if (pre == null) pre = root.val;

else {

if (root.val <= pre) return false;

else pre = root.val;

}

return isValidBST(root.right);

}

return false;

}

}

Q4.8  首个共同祖先

设计并实现一个算法,找出二叉树中某两个节点的第一个共同祖先。不得将其他的节点存储在另外的数据结构中。注意:这不一定是二叉搜索树。

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

3

/ \

5   1

/ \ / \

6  2 0  8

/ \

7   4

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

输出: 3

解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

输出: 5

解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }

*/

class Solution {

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

if(root == null)

return null;

if(p == root || q == root)

return root;

TreeNode l = lowestCommonAncestor(root.left, p, q);

TreeNode r = lowestCommonAncestor(root.right, p, q);

if(l != null && r != null)

return root;

return l == null ? r : l;

}

}

Q4.9  二叉搜索树序列

从左向右遍历一个数组,通过不断将其中的元素插入树中可以逐步地生成一棵二叉搜索树。给定一个由不同节点组成的二叉搜索树,输出所有可能生成此树的数组。

示例:

给定如下二叉树

2

/ \

1   3

返回:

[

[2,1,3],

[2,3,1]

]

分析:

根据题意分析可知,插入元素的顺序必须从根节点开始插入,也就是先插入2后,才可以插入1和3。那么我们维护一个可以访问的节点列表,每轮递归都依次访问列表中的元素,当访问元素有孩子结点时,把孩子结点加入到列表中,然后再去依次访问列表中的元素,当列表为空时,表示产生了一个有效的序列,把它加入到结果集当中。注意访问结点时,要先在列表中删除掉,访问结束后记得恢复。

/**

  • 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> BSTSequences(TreeNode root) {

res = new LinkedList<>();

if(root == null){

res.add(new LinkedList<>());

return res;

}

LinkedList list = new LinkedList<>();

LinkedList path = new LinkedList<>();

path.add(root.val);

getSequences(root, list, path);

return res;

}

private void getSequences(TreeNode root, LinkedList list, LinkedList path){

if(root == null){

return;

}

if(root.left != null)

list.add(root.left);

if(root.right != null)

list.add(root.right);

if(list.isEmpty()){

res.add(new LinkedList<>(path));

return;

}

int len = list.size();

for(int i = 0; i < len; ++i){

TreeNode cur = list.get(i);

list.remove(i);

path.add(cur.val);

getSequences(cur, new LinkedList<>(list), path);

path.removeLast();

list.add(i, cur);

}

}

private List<List> res;

}

Q4.10  检查子树

检查子树。你有两棵非常大的二叉树:T1,有几万个节点;T2,有几万个节点。设计一个算法,判断 T2 是否为 T1 的子树。

如果 T1 有这么一个节点 n,其子树与 T2 一模一样,则 T2 为 T1 的子树,也就是说,从节点 n 处把树砍断,得到的树与 T2 完全相同。

示例1:

输入:t1 = [1, 2, 3], t2 = [2]

输出:true

示例2:

输入:t1 = [1, null, 2, 4], t2 = [3, 2]

输出:false

思路:遍历二叉树t1的每一个节点,看能否找到以该节点为根的树与t2相同。

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }

*/

class Solution {

public static boolean isSame(TreeNode t1, TreeNode t2) {

//当同时到达叶子节点的后继(都为空),依然没返回false,就返回true

if (t1 == null && t2 == null) {

return true;

}

//待比较的两个节点一个为空,另一个不为空,说明这两棵树不相等

if (t1 == null || t2 == null) {

return false;

}

//如果待比较的两个节点都不为空,就比较它们的值是否相等,如果值相等就继续判断它们的左、右子树是否相等

return t1.val == t2.val && isSame(t1.left, t2.left) && isSame(t1.right, t2.right);

}

public boolean checkSubTree(TreeNode t1, TreeNode t2) {

//如果遍历到达的节点为空,则判断t2是否也为空,若是返回true,不是返回false

if (t1 == null) {

return t2 == null;

}

//遍历t1的每一个节点,看能否找到一棵子树与t2相同

return isSame(t1, t2) || (checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2));

}

}

Q4.12  求和路径

给定一棵二叉树,其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法,打印节点数值总和等于某个给定值的所有路径的数量。注意,路径不一定非得从二叉树的根节点或叶节点开始或结束,但是其方向必须向下(只能从父节点指向子节点方向)。

示例:

给定如下二叉树,以及目标和 sum = 22,

5

/ \

4   8

/   / \

11  13  4

/  \    / \

7    2  5   1

返回:

3

解释:和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7]

class Solution {

public int pathSum(TreeNode root, int sum) {

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

4   8

/   / \

11  13  4

/  \    / \

7    2  5   1

返回:

3

解释:和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7]

class Solution {

public int pathSum(TreeNode root, int sum) {

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-KyPfxSTp-1715411698068)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值