【Data structure&Algorithm】二叉树相关题目

236. 二叉树的最近公共祖先

题目
二叉树的递归框架:

void traverse(TreeNode root) {
    // 前序遍历
    traverse(root.left)
    // 中序遍历
    traverse(root.right)
    // 后序遍历
}

套入该题目给的函数:

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode leftResult = lowestCommonAncestor(root.left,p,q);
        TreeNode rightResult = lowestCommonAncestor(root.right,p,q);
    }

然后对框架进行“添油加醋”,具体需要思考以下3个问题:
1、这个函数是干嘛的?
2、这个函数参数中的变量是什么?
3、得到函数的递归结果后,应该干什么?

现在对这3个问题一个一个进行回答。
1、这个函数是干嘛的?
给该函数输入三个参数root,p,q,它会返回一个节点。我们来定义一下具体的规则。
规则1:如果p、q都在以root为根的树中,返回p、q的最近公共祖先节点
规则2:如果p、q都不在以root为根的树中,返回null
规则3:
3.1如果只有p在以root为根的树中,而q不在,返回p
3.2如果只有q在以root为根的树中,而p不在,返回q

2、这个函数参数中的变量是什么?
p、q随着递归的进行并不会改变,发生改变的是root,因为会不断传入root.left和root.right

3、得到函数的递归结果后,应该干什么?
base case对传入的root进行讨论:
情况1:root为空,返回null
情况2:
2.1 root=q,若p在以root(q)为根节点的树中,则应返回root(q);若p不在以root(q)为根节点的树中,根据“规则3.2”,则应返回root(q)。即root=q时,返回root。
2.2 同理,root=p时,返回root。

对递归调用的结果leftResult、rightResult进行讨论:
情况1:
1.1 如果leftResult为null、rightResult不为null,说明p、q的最近公共祖先为rightResult,返回rightResult
1.2 如果leftResult不为null、rightResult为null,说明p、q的最近公共祖先为leftResult,返回leftResult
情况2:
如果leftResult、rightResult均为null,说明p、q既不在root的左子树中,也不在root的右子树中,没有公共祖先,返回null
情况3:
如果leftResult、rightResult均不为null,应该对应“规则3”,p在以leftResult为根的节点中,q在以rightResult为根的节点中,或者是q在以leftResult为根的节点中,p在以rightResult为根的节点中,总之就是p、q的最近公共祖先为root,返回root。

完整代码:

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //base case,对root进行讨论
        if(root == null){
            return null;
        }
        if(root == p||root == q){
            return root;
        }
        TreeNode leftResult = lowestCommonAncestor(root.left,p,q);
        TreeNode rightResult = lowestCommonAncestor(root.right,p,q);

        //对递归调用的结果进行讨论
        if(leftResult == null && rightResult != null){
            return rightResult;
        }

        if(leftResult != null && rightResult == null){
            return leftResult;
        }

        if(leftResult == null && rightResult == null){
            return null;
        }

        //if(leftResult != null && rightResult != null)
        return root;
    }

341. 扁平化嵌套列表迭代器

题目
先要读懂题目意思,这道题的题意较难理解,理解以下几个点:

  1. NestedInteger数据结构:题目给出的是个接口,给了3个抽象方法,实际的NestedInteger数据结构我们是可以脑补出来的。最后给出这个脑补的数据结构。
  2. 给出的3个函数:构造函数、next()、hasNext()

还要知道List集合的迭代器,通过iterator()方法获取迭代器,迭代器本身有next()、hasNext()方法,含义跟本题中要写的两个同名方法意义相同。

List<Integer> result = new LinkedList<>();
……
Iterator<Integer> it = result.iterator();

代码:

public class NestedIterator implements Iterator<Integer> {
    //扁平化结果list的迭代器
    Iterator<Integer> it = null;

    //构造函数
    public NestedIterator(List<NestedInteger> nestedList) {
        //list存放扁平化后的结果
        List<Integer> result = new LinkedList<>();
        for(NestedInteger nI : nestedList){
            traverse(nI,result);
        }
        this.it = result.iterator();
    }

    @Override
    public Integer next() {
        return it.next();
    }

    @Override
    public boolean hasNext() {
        return it.hasNext();
    }

    public void traverse(NestedInteger nI,List<Integer> result){
        //是整数,添加进结果list
        if(nI.isInteger()){
            result.add(nI.getInteger());
            return;
        }
        //是list,继续递归
        for(NestedInteger nI_:nI.getList()){
            traverse(nI_,result);
        }
    }
}

NestedInteger数据结构

public class NestedInteger {
    private Integer val;
    private List<NestedInteger> list;

    public NestedInteger(Integer val) {
        this.val = val;
        this.list = null;
    }
    public NestedInteger(List<NestedInteger> list) {
        this.list = list;
        this.val = null;
    }

    // 如果其中存的是一个整数,则返回 true,否则返回 false
    public boolean isInteger() {
        return val != null;
    }

    // 如果其中存的是一个整数,则返回这个整数,否则返回 null
    public Integer getInteger() {
        return this.val;
    }

    // 如果其中存的是一个列表,则返回这个列表,否则返回 null
    public List<NestedInteger> getList() {
        return this.list;
    }
}

NestedInteger数据结构与N叉树的相似性

[[1,1],2,[1,1]]这种结构,实际相当于是N叉树,可以看看两者的数据结构对比:

class NestedInteger {
    Integer val;
    List<NestedInteger> list;
}

/* 基本的 N 叉树节点 */
class TreeNode {
    int val;
    TreeNode[] children;
}

在这里插入图片描述
所以就可以使用N叉树的遍历框架:

void traverse(TreeNode root) {
    for (TreeNode child : root.children)
        traverse(child);
### 回答1: data structure and algorithm analysis in c是一本C语言数据结构算法分析的经典教材,由Mark Allen Weiss编写。该书的主要特点是对数据结构算法的讲解非常详细且透彻,采用了很多实例进行讲解,使得读者可以很快地掌握这些内容。此外,该书还特别强调了算法分析设计的重要性,帮助读者理解复杂算法的实现方式,提高算法的优化能力。 而data structure and algorithm analysis in c的下载方式也非常简单,可以在网上找到相关的资源下载,且也可以通过购买实体书的方式获得。对于想要深入学习C语言数据结构算法分析的人来说,这本书是非常得推荐的一本入门教材。 ### 回答2: data structure and algorithm analysis in c是一本关于C语言数据结构算法分析的经典教科书。该书涵盖了广泛的数据结构算法,包括数组、链表、树、图、排序、查找等。本书不仅涵盖了基本概念技术,而且提供了深入的分析高级应用。书中有丰富的例子习题,方便读者深入理解应用。该书是学习数据结构算法的好材料,对于提高程序员的编程能力解决问题的能力有很大的帮助。 ### 回答3: Data Structure and Algorithm Analysis in C是一本面向C++程序设计开发人员的算法数据结构分析书籍。它涵盖了许多重要的算法数据结构,如排序搜索算法二叉树,平衡树图论等方面。本书旨在帮助读者深入了解算法数据结构的基本知识,提供了许多实用的示例演练题来帮助读者巩固自己的知识。 本书包含了许多实际的示例演练题,这些题目涵盖了从简单到复杂的各种情况,有助于读者更好地理解应用所学知识。与此同时,这本书也提供了大量的编码调试技巧,帮助读者编写出高效可维护的代码。 总之,Data Structure and Algorithm Analysis in C是一本优秀的参考书,无论你是刚接触算法数据结构或是已经具备一定的基础,它都可以提供丰富的知识实践经验。如果你正在寻找一本深入了解算法数据结构的书籍,那么它一定是首选之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值