《五月集训》第十七天——广度优先搜索


前言

        宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
刷题坚持每一天,以下题目引用自:力扣(LeetCode)

💎一、题目一

🏆1.题目描述

原题链接:LCP 44. 开幕式焰火

        「力扣挑战赛」开幕式开始了,空中绽放了一颗二叉树形的巨型焰火。
        给定一棵二叉树 root 代表焰火,节点值表示巨型焰火这一位置的颜色种类。请帮小扣计算巨型焰火有多少种不同的颜色。

示例 1:
输入:root = [1,3,2,1,null,2]
输出:3
解释:焰火中有 3 个不同的颜色,值分别为 1、2、3

🏆2.解题思路

🔑思路:

​         二叉树的层序遍历+hash计数,通过链式队列实现。

🏆3.代码详解

typedef struct {
    struct TreeNode* date;
    struct linklist* next;
}linklist;
typedef struct {
	linklist* front;
	linklist* rear;
}linkqueue;
bool queue_empyt(linkqueue* obj){     //队列是否为空
    return obj->front == obj->rear;
}
void enqueue(linkqueue* obj, struct TreeNode* x){     //入队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node->date = x;
    node->next = NULL;
    obj->rear->next = node;
    obj->rear = obj->rear->next;
}
struct TreeNode* dequeue(linkqueue* obj){    // 出队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node = obj->front;
    obj->front = node->next;
    node->next = NULL;
    free(node);
    node = NULL;
    return obj->front->date;
}
int numColor(struct TreeNode* root){
    linkqueue* fire = (linkqueue*)malloc(sizeof(linkqueue));
    fire->front = fire->rear = (linklist*)malloc(sizeof(linklist));
    fire->front->date = 0;
    fire->front->next = NULL;
    struct TreeNode* newr = root;
    struct TreeNode* centrce;
    int count = 0;
    int hash[1001] = {0};
    enqueue(fire, newr);
    while(!queue_empyt(fire)){
        newr = dequeue(fire);
        if(!hash[newr->val]){
            ++hash[newr->val];
            ++count;
        }
        if(newr->left) enqueue(fire, newr->left);
        if(newr->right) enqueue(fire, newr->right);
    }
    return count;
}

💎二、题目二

🏆1.题目描述

原题链接:102. 二叉树的层序遍历

        给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:
Alt
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

🏆2.解题思路

🔑思路:

​         二叉树的层序遍历,和上题代码相同。在输出处理上逻辑不同。

🏆3.代码详解

typedef struct {
    struct TreeNode* date;
    struct linklist* next;
}linklist;
typedef struct {
	linklist* front;
	linklist* rear;
}linkqueue;
bool queue_empyt(linkqueue* obj){     //队列是否为空
    return obj->front == obj->rear;
}
void enqueue(linkqueue* obj, struct TreeNode* x){     //入队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node->date = x;
    node->next = NULL;
    obj->rear->next = node;
    obj->rear = obj->rear->next;
}
struct TreeNode* dequeue(linkqueue* obj){    // 出队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node = obj->front;
    obj->front = node->next;
    node->next = NULL;
    free(node);
    node = NULL;
    return obj->front->date;
}

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    * returnSize = 0;
    if(root == NULL) return NULL;
    linkqueue* fire = (linkqueue*)malloc(sizeof(linkqueue));
    fire->front = fire->rear = (linklist*)malloc(sizeof(linklist));
    fire->front->date = 0;
    fire->front->next = NULL;
    struct TreeNode* newr = root;
    int row = 0;
    int head = 0, tail = 0;
    int** ans = (int**)malloc(sizeof(int*)*2001);
    * returnColumnSizes = (int*)malloc(sizeof(int)*1024);
    enqueue(fire, newr);
    ++tail;
    while(!queue_empyt(fire)){
        int returnCol = 0, nowrear = tail;
        ans[row++] = (int*)malloc(sizeof(int)*(nowrear - head));
        while(head < nowrear){
            newr = dequeue(fire);
            ++head;
            ans[row-1][returnCol++] = newr->val;
            if(newr->left){
                enqueue(fire, newr->left);
                ++tail;
            } 
            if(newr->right){
                enqueue(fire, newr->right);
                ++tail;
            }   
        }
        (*returnColumnSizes)[row-1] = returnCol;
    }
    *returnSize = row;
    free(fire);
    return ans;
}

💎三、题目三

🏆1.题目描述

原题链接:1609. 奇偶树

如果一棵二叉树满足下述几个条件,则可以称为 奇偶树 :

  • 二叉树根节点所在层下标为 0 ,根的子节点所在层下标为 1 ,根的孙节点所在层下标为 2 ,依此类推。
  • 偶数下标 层上的所有节点的值都是 奇 整数,从左到右按顺序 严格递增
  • 奇数下标 层上的所有节点的值都是 偶 整数,从左到右按顺序 严格递减

给你二叉树的根节点,如果二叉树为 奇偶树 ,则返回 true ,否则返回 false 。

示例 1:
Alt
输入:root = [1,10,4,3,null,7,9,12,8,6,null,null,2]
输出:true
解释:每一层的节点值分别是:
0 层:[1]
1 层:[10,4]
2 层:[3,7,9]
3 层:[12,8,6,2]
由于 0 层和 2 层上的节点值都是奇数且严格递增,而 1 层和 3 层上的节点值都是偶数且严格递减,因此这是一棵奇偶树。

🏆2.解题思路

🔑思路:

​        还是原来的二叉树层序遍历代码,与上一题不同的是对每个节点值和行的处理。

🏆3.代码详解

typedef struct node{
    struct TreeNode* date;
    struct node* next;
}linklist;
typedef struct {
	linklist* front;
	linklist* rear;
}linkqueue;
bool queue_empyt(linkqueue* obj){     //队列是否为空
    return obj->front == obj->rear;
}
void enqueue(linkqueue* obj, struct TreeNode* x){     //入队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node->date = x;
    node->next = NULL;
    obj->rear->next = node;
    obj->rear = obj->rear->next;
}
struct TreeNode* dequeue(linkqueue* obj){    // 出队
    linklist* node = (linklist*)malloc(sizeof(linklist));
    node = obj->front;
    obj->front = node->next;
    node->next = NULL;
    free(node);
    node = NULL;
    return obj->front->date;
}

bool isEvenOddTree(struct TreeNode* root){
    if(root == NULL) return NULL;
    linkqueue* fire = (linkqueue*)malloc(sizeof(linkqueue));
    fire->front = fire->rear = (linklist*)malloc(sizeof(linklist));
    fire->front->date = 0;
    fire->front->next = NULL;
    struct TreeNode* newr = root;
    int row = -1;
    int head = 0, tail = 0;
    int min = -1, max = 1000001;
    enqueue(fire, newr);
    ++tail;
    while(!queue_empyt(fire)){
        int returnCol = 0, nowrear = tail;
        ++row;
        min = -1;
        max = 1000001;
        while(head < nowrear){
            newr = dequeue(fire);
            ++head;
            if(row & 1){
                if((newr->val & 1) == 1) return false;
                if(newr->val < max) max = newr->val;
                else return false;
            }
            else if((row & 1) == 0){
                if((newr->val & 1) == 0) return false; 
                if(row > 0){
                    if(newr->val > min) min = newr->val;
                    else return false;
                }    
            }
            if(newr->left){
                enqueue(fire, newr->left);
                ++tail;
            } 
            if(newr->right){
                enqueue(fire, newr->right);
                ++tail;
            }   
        }
    }
    return true;
}


💎四、星球推荐

        星球链接:英雄算法联盟

星球里有什么?
        【朋友圈】一个极致精准的自律、编程、算法的小圈子。
        【算法集训】以月为单位组织算法集训,每天四题,风雨无阻。
        【排行榜】每天、每周都会有榜单,激励大家不断进步,不断成长。
        【个人规划】每个人都写好自己的规划,也可以查看他人的规划,时刻警醒自己不掉队。
        【打卡挑战】每日一题打卡、每日早起打卡、算法集训打卡、规划完成情况打卡。
在星球里做什么?
        目前星球人数达到420+,在星球里你能够遇到一群志同道合之人,因为都是花钱进来的,你不会看到任何浑水摸鱼的人,每个人都有自己的每月规划,星主每月都会组织算法集训,每天一起刷题,你可以看到别人的解题报告,取其之长,补己之短。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值