数据结构面试题5

一、判断是否是完全二叉树

1、法一

1>如果树为空,则直接返回错
2>如果树不为空:层序遍历二叉树
2.1>如果一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列;
2.1>如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
2.2>如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;该树才是完全二叉树,否则就不是完全二叉树;

public  boolean isCompleteTree(BTNode root)
{
     if(root==null)
     {
         return true;
     }
     Queue<BTNode> q=new LinkedList<>();
     q.offer(root);
     //是叶子节点或者只有左孩子的节点,也就是这两种不饱和的节点出现之后还需要判断后面的节点是否有孩子
     // 如果只有右孩子的不饱和节点一定不是完全二叉树
    // 一开始让不饱和节点置为false,找到之后设为true
    boolean isLeafOrLeft=false;
    while(!q.isEmpty()) {
        BTNode cur = q.poll();
        //得到第一个不饱和节点之后
        if (isLeafOrLeft) {
             //从第一个不饱和结点之后,所有节点不能有孩子
            if (null != cur.left || null != cur.right) {
                System.out.println("该二叉树不是完全二叉树");
                return false;
            }
       }//没找到不饱和节点就继续按照层序遍历寻找
       else {
            //cur节点左右孩子都存在
            if (null != cur.left && null != cur.right) {
                q.offer(cur.left);
                q.offer(cur.right);
            } else if (null != cur.left) {
                //只有左孩子:找到不饱和节点,标记isLeafOrLeft=true
                q.offer(cur.left);
                isLeafOrLeft = true;
            } else if (null != cur.right) {
                //只有右孩子:找到不饱和节点,一定不是完全二叉树,返回false
                System.out.println("该二叉树不是完全二叉树");
                return false;
            } else {
                //cur是叶子节点:找到不饱和节点:标记isLeafOrLeft=true
                isLeafOrLeft = true;
            }
        }
    }
    System.out.println("该二叉树是完全二叉树");
    return true;
}

二、判断是否是满二叉树

满二叉树的定义:一个高度为h,并且含有2^h - 1个节点的二叉树称为满二叉树,下文称呼满二叉树为FBT。
根据满二叉树的高度与节点个数之间的关系,很容易判断一棵树是否为FBT,只需要求树其树高和节点个数即可。

三、求二值矩阵中最大的面积

给你一个二维矩阵,权值为False和True,找到一个最大的矩形,使得里面的值全部为True,输出它的面积。

1、法一

就是暴力遍历二维数组中的每一个元素,然后求出该元素所在区域的最大矩形的面积,但是这种方法的时间复杂度太高,不建议这样子做。

2、法二

  • 创建一个空栈
  • 从第一个矩形条开始,对每个矩形条的高度height[i] (i的取值范围是[0,n-1])执行下面两步
    a) 如果栈为空,或height[i]大于等于栈顶元素,那么将矩形条i压入栈中。
    b) 如果输入的矩形条高度小于栈顶元素高度,那么将栈顶元素在输入数组中的索引tp出栈,然后计算矩形面积。矩形的高为height[tp],而右边界为i,左边界为当前栈顶元素对应的索引,若栈为空,则宽度就是i。
  • 经过计算后,栈非空,然后将栈中元素逐个弹出,并按照步骤2计算矩形面积,并且更新最大值。

3、动态规划

红色的部分就为面积最大的方阵(方阵内元素都是1)。

我们可以新建一个矩阵,和原来的矩阵同样大小,但是这个矩阵内元素是存储着,以当前元素为方阵最右下角的元素的最大面积,像是上图中红色的那个方阵,右下角元素,就存着这个方阵的面积,但是这个元素的大小怎么求,是我接下来要讲的,新矩阵的元素是这么填充的,取这个元素的上方元素,左方元素,对角线元素,这几个元素都存着的是面积,如果将面积映射为01矩阵的话是不是应该有一个交集,
现在要求以红色圆圈为有下角元素的最大方阵面积,那么此元素的左方元素的最大面积应该是深蓝色方框内的方阵的面积,上方最大面积应该是红色方框内的面积,对角元素的最大面积应该是浅蓝色方框内的面积,那么黑色方框内的方阵就是我们要求的最大面积,大家请看红色方框和看蓝色方框内的区域完全包含在黑色方框内,也就是说要求的方阵是不是比完全包含在黑框方阵内的区域(浅蓝色和红色方框),多一行一列啊,图画多了就会发现,要求的方阵的区域只会包含左,上,对角三个区域中最小的一个区域也就是,面积最小的区域,那么这个区域的边其实就是比要求区域的边短1,所以求出最小的面积,技能就去最小面积的边,那么就能求出要求的面积。那么新的矩阵每个元素就都可以算出来,所以最大面积应该就存储在这个新的矩阵内,所以从此矩阵取出最大元素就是,最大的面积。这就是运用了动态规划的思想。

4、 Histogram法

https://blog.csdn.net/a745233700/article/details/82056236

四、连通域

五、二分法各种实现(递归与非递归)

https://blog.csdn.net/Leran_daydayup/article/details/103117620?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=1619620147492_16047&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

六、桶排序和计数排序

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容