面试回忆录:链表&&二叉树

这篇具有很好参考价值的文章主要介绍了面试回忆录:链表&&二叉树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

导语:

        链表与二叉树都是非常基础且非常重要的数据结构,这类题目在找工作面试中是非常高频的考题,非常考验基本功。作者在曾经在面试过程中,被要求现场写过的两道题目,分别是关于二叉树和链表的,因此对这两道题目记忆比较深刻。所以写下这篇博客与读者分享。

一.二叉树--求祖父节点值为偶数的节点和

LeetCode题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述:

        给你一棵二叉树,请你返回满足以下条件的所有节点的值之和:

        该节点的祖父节点的值为偶数。(一个节点的祖父节点是指该节点的父节点的父节点。)

如果不存在祖父节点值为偶数的节点,那么返回 0 。

示例:

面试回忆录:链表&&二叉树,链表,数据结构

输入:root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
输出:18
解释:图中红色节点的祖父节点的值为偶数,蓝色节点为这些红色节点的祖父节点。

思路分析:

        作者第一次看到此题的思路是采用递归的方法,深度优先遍历二叉树,取偶数的节点,将其孙子节点的值进行累加,代码如下:

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    sum1 = 0  # 用于存储累加的结果

    def sumEvenGrandparent(self, root: TreeNode):
        if root is None:
            return 0

        if root.val % 2 == 0:  # 如果当前节点的值为偶数,则遍历其孙子节点,并将子节点的值累加到sum1中
            a = root.left
            b = root.right
            self.addchild(a)
            self.addchild(b)

        # 递归调用,对左子树和右子树进行遍历
        self.sumEvenGrandparent(root.left)
        self.sumEvenGrandparent(root.right)
        
        return self.sum1

    def addchild(self, a):
        if a is not None:
            if a.left is not None:
                self.sum1 += a.left.val  # 将左孙子节点的值累加到sum1中
            if a.right is not None:
                self.sum1 += a.right.val  # 将右孙子节点的值累加到sum1中

可以看到代码容易理解,但是代码较长,执行时间偏长:

面试回忆录:链表&&二叉树,链表,数据结构

随后作者参考别人的答案,定义一个接收三个参数的函数,三个参数分别是祖父节点,父节点和本节点,这样可以使代码简化很多,代码如下:

class Solution:
    def sumEvenGrandparent(self, root: TreeNode) -> int:
        # 初始化一个变量来保存偶数祖父节点的值之和
        sum1 = 0

        # 定义一个深度优先搜索函数,用于遍历树节点
        def dfs(gr_val, p_val, node):
            if node is None:  # 如果节点为空,直接返回
                return
            if gr_val % 2 == 0:  # 判断祖父节点的值是否为偶数
                nonlocal sum1  # 使用nonlocal关键字声明在外部作用域中的sum1变量
                sum1 += node.val  # 累加当前节点的值到sum1
            # 递归调用,将当前节点的值作为父节点的值,左孩子和右孩子作为当前节点继续递归
            dfs(p_val, node.val, node.left)
            dfs(p_val, node.val, node.right)

        # 调用深度优先搜索函数,初始的祖父节点和父节点的值都为1,从根节点开始遍历
        dfs(1, 1, root)

        # 返回偶数祖父节点值之和
        return sum1

可以看到代码长度减少了,执行速度也稍微变快了点 ,两次代码的时间复杂度都为O(n)

面试回忆录:链表&&二叉树,链表,数据结构

 二.链表--两数相加

LeetCode题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述:

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

面试回忆录:链表&&二叉树,链表,数据结构

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

思路分析:

        因为本题涉及到个位数的相加问题和进位问题,所以要定义个位数num_0和十位数num_10,又由于列表的遍历需要设置一个一直在动的指针,所以需要同时创建一个不动的定指针dum,用于返回链表的头节点。然后就可以遍历l1和l2两个链表,直到两个链表都为空,且十位数为空的情况下才结束,遍历过程中通过对10取余和对10整除来获得个位数和十位数,并将个位数存入新链表的当前节点处,十位数作为进位放到下一次两值相加的适合用,最后返回链表的头节点即可。代码如下:

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        # 初始化两个变量用于存储当前位的数字和进位
        num_0 = 0
        num_10 = 0
        # 创建一个哑结点,并将 cur 指针指向哑结点
        cur = dum = ListNode()

        # 遍历两个链表,直到两个链表和进位都为0时结束
        while l1 or l2 or num_10:
            # 如果 l1 为空,则将当前节点的值设为 0
            if l1 is None:
                l1 = ListNode(0)
            # 如果 l2 为空,则将当前节点的值设为 0
            if l2 is None:
                l2 = ListNode(0)
            # 计算当前位上的数字和进位的和,并取余得到当前位的值
            num_0 = (l1.val + l2.val + num_10) % 10
            # 计算进位值
            num_10 = (l1.val + l2.val + num_10) // 10
            # 创建新的节点,并将当前位的值赋给它
            cur.next = ListNode(num_0)
            # 移动 l1 和 l2 到它们的下一个节点
            l1 = l1.next
            l2 = l2.next
            # 移动 cur 到下一个节点
            cur = cur.next
        
        # 返回哑结点的下一个节点,即为相加后的链表头节点
        return dum.next

可以看到执行时间还是挺快的,代码的简洁性也比较高。 代码的时间复杂度为 O(max(m, n))

面试回忆录:链表&&二叉树,链表,数据结构

三.总结

        上述两题皆为作者在面试时遇到的真题,面试官要求现场手写,现场环境非常紧张,没有太多时间思考,需要完全掌握才能写的出来。链表和二叉树都是比较重要且基础的数据结构,面试的过程中出题概率基本上百分之百。

        其中链表的核心遍历语句是cur=cur.next,而二叉树的遍历则分为深度优先遍历DFS和广度优先遍历BFS,深度遍历利用递归的思想,广度遍历则是采用队列的思想,python里有一个数据结构queue=collections.deque([root]),因其进出队列效率较高,通常用于遍历二叉树。在广度优先遍历时,为了操作层数,通常会对队列的长度进行操作:for _ in range(len(queue)),这样可以保证队列中的该层元素弹出完毕再开始下一层元素的弹出操作。

        总之同学们需要在掌握遍历链表和二叉树的基础上, 深入理解链表和二叉树的原理。文章来源地址https://www.toymoban.com/news/detail-786948.html

到了这里,关于面试回忆录:链表&&二叉树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java常见的数据结构:栈、队列、数组、链表、二叉树、二叉查找树、平衡二叉树、红黑树

    数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 栈 队列 数组 链表 二叉树 二叉查找树 平衡二叉树 红黑树... 后进先出,先进后出 数据进入栈模型的过程称为

    2024年02月07日
    浏览(45)
  • 常见的数据结构(顺序表、顺序表、链表、栈、队列、二叉树)

    线性表(Linear List)     1.什么是线性表     2.线性表的特点     3.线性表的基本运算 顺序表     1.什么是顺序表     2.时间复杂度: 链表     1.什么是链表     2.单向链表     3. 双向链表     4.ArrayList和LinkedList的使用 栈Stack     1.什么是栈     2.栈的基本方法 队列Queue

    2024年02月13日
    浏览(38)
  • 【数据结构】二叉树面试题

    目录 1.二叉树的最大深度 2.相同的树 3.另一棵树的子树 4.翻转二叉树 5.平衡二叉树 6.对称二叉树 7.完全二叉树 8.二叉树遍历 9.层序遍历 10.根据中序和前序序列构造二叉树 11.根据中序和后序序列构造二叉树 12.二叉树的最近公共祖先 13.非递归前序遍历 14.非递归中序遍历 15.非递

    2024年02月11日
    浏览(40)
  • 数据结构三叉链表与线索二叉树的思路与实现详解

    ❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 我们知道最常见的链式存储二叉树的结构体中有数据域、左孩子指针以及右孩子指针,通过递归来创建二叉树。显而易见的是,想找到二叉树中任意一个结点的 前驱 或 后

    2024年02月02日
    浏览(60)
  • 【数据结构】 二叉树面试题讲解->贰

    二叉树的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于二叉树的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序

    2024年02月10日
    浏览(44)
  • 【数据结构】 二叉树面试题讲解->壹

    二叉树的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于二叉树的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同

    2024年02月10日
    浏览(49)
  • 【数据结构】 二叉树面试题讲解->叁

    二叉树的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于二叉树的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字

    2024年02月09日
    浏览(33)
  • 【数据结构大全】你想要的都有,数组、链表、堆栈、二叉树、红黑树、B树、图......

    作者简介: 目录 1.概述 2.线性结构 3.时间复杂度 4.查找算法 5.树 6.图 博主之前写过一个完整的关于数据结构的系列文章,一共十三篇,内容包含,数组、链表、堆栈、队列、时间复杂度、顺序查找、二分查找、二叉树、二叉搜索树、平衡二叉树、红黑树、B树、B+树、大顶堆

    2024年02月10日
    浏览(46)
  • C++数据结构与算法详解:链表、栈、队列、树、二叉树和图结构的实现与应用

    链表是一种常见的数据结构由一系列节点按顺序连接而成,一般每个节点包含一个数据元素和一个指向下一个节点的引用。 链表有多种类型: 单向链表:每个节点只有一个指向下一个节点的引用 双向链表:每个节点有一个指向前一个节点和一个指向后一个节点的引用 循环链

    2024年02月04日
    浏览(51)
  • 探索树形数据结构,通识树、森林与二叉树的基础知识(专有名词),进一步利用顺序表和链表表示、遍历和线索树形结构

      结点之间有分支,具有层次关系 树的定义 : 树 (tree)是n(n≥0)个有限集。 若n = 0,则称为空树; 若n 0,则它满足如下两个条件: 有且仅有一个特定的称为根(Root)的结点; 其余结点可分为m(m≥0)个互不相交的有限集T1,T2,T3,.....,Tm,其中每一个集合本身又是一棵树,并称为根的

    2024年02月01日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包