【第三届字节跳动青训营|刷题打卡】DAY3

3,694 阅读2分钟
  • 为了助力本届青训营课程的学习,青训营项目组为同学们精心挑选了练手习题 📖
  • 每两天发布一篇,包含选择题和实操题各一题(第二天将发布答案解析)🥳
  • 同学们可以在评论区留下你的解题过程并进行互动交流 ✍️

一、【多选】绝大多数硬盘可以提供哪些写入保证?

a. 单个sector原子写入
b. 单个page原子写入
c. 硬盘顺序执行文件系统发送的操作
d. 以上都不可以

答案 & 解析

d;
本题主要考察对于一个数据密集型应用开发者(比如数据库开发者、文件系统开发者),在数据不能出错的前提下,可以依赖磁盘的哪些能力,事实证明几乎没有什么能力可以依赖。
在随时可能断电的情况下,大多数硬件能提供单个sector的原子性写入;但是也有少数硬件连单个sector的写入都无法保证;如果一个page对应多个sector,则单个page的完整写入总是无法得到保障。更加详细的情况可以查看这个讨论:crash - Are disk sector writes atomic?
对于同时发给硬盘的多个操作(比如写多个不连续的sector),硬盘并不保证操作的顺序。结合其弱原子性,所以硬盘可能处在任何一个中间状态。这主要是由于机械硬盘的寻址优化策略和固态/机械硬盘的缓存策略导致的。

二、判断一棵二叉树是否是平衡二叉树。(平衡二叉树要求:树中节点左右子树树高差不超过1。)

答案 & 解析

解法一(常规解法):
分别求左右子树的深度,再进行判断、递归。(此方法会遍历一个节点多次,效率不高。)

bool IsBalanced_Solution1 (BinaryTreeNode * pRoot )
{
    if ( pRoot == NULL ) return true ;
    int left = TreeDepth ( pRoot->m_pLeft );
    int right = TreeDepth ( pRoot->m_pRight );
    int diff = left - right ;
    if ( diff >1|| diff <-1 ) return false ;
    return IsBalanced_Solution1 ( pRoot - >m_pLeft ) && IsBalanced_Solution1 ( pRoot - >m_pRight );
}

解法二(更高效的解法):
解决了遍历一个问题多次的问题。用后序遍历的方式遍历二叉树的每一个节点,在遍历到一个节点之前我们就已经遍历了它的左右子树。只要在遍历每个节点的时候记录深度,就可以一边遍历一边判断每个节点是不是平衡的。

bool IsBalanced_Solution2(BinaryTreeNode * pRoot)
{
    int depth =0 ;
    return IsBalanced(pRoot,& depth);
}
bool IsBalanced(BinaryTreeNode * pRoot, int* pDepth)
{
    if (pRoot == NULL)
    {
        *pDepth=0 ;
        return true ;
    }
    int left, right;
    if (IsBalanced(pRoot-> m_pLeft,& left) && IsBalanced(pRoot-> m_pRight,& right))
    {
        int diff = left - right;
        if (diff <=1&& diff>=-1 )
        {
            *pDepth = 1 + (left> right ? left : right);
            return true ;
        }
    }
    return false ;
}

今天是刷题打卡第三天啦,同学们冲鸭~