《五月集训》第二十七日——图

前言

这是五月集训的第二十七日,今日的训练内容是

解题报告

1.力扣1791

原题链接

1791. 找出星型图的中心节点

题目概述

有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。

给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。

解题思路

一上来看到题目的思路是创建一个哈希表,然后出现过不止一次的结点就直接返回那个结点,其实浪费了非常多的内存。实际上只需要两组数据就可以得到中心结点了。因为每组数据都有一个结点是中心结点,那么只要随便取两组数据返回重复部分就可以了,不需要使用到哈希表。

源码剖析

int findCenter(int** edges, int edgesSize, int* edgesColSize){
    if(edges[0][0]==edges[1][0]) return edges[0][0];
    else if(edges[0][0]==edges[1][1]) return edges[0][0];
    else return edges[0][1];
}

2.力扣797

原题链接

797. 所有可能的路径

题目概述

给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)

graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。

解题思路

使用一个栈来储存遍历过程中的路径,然后使用dfs对路径进行遍历,因为这是一个用向且没有环的图,所以相当简单,直接遍历到底就可以了。

源码剖析

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** ans;
int stk[15];
int stkSize;

void dfs(int x, int n, int** graph, int* graphColSize, int* returnSize, int** returnColumnSizes) {
    if (x == n) {
        int* tmp = malloc(sizeof(int) * stkSize);
        memcpy(tmp, stk, sizeof(int) * stkSize);
        ans[*returnSize] = tmp;
        (*returnColumnSizes)[(*returnSize)++] = stkSize;
        return;
    }
    for (int i = 0; i < graphColSize[x]; i++) {
        int y = graph[x][i];
        stk[stkSize++] = y;
        dfs(y, n, graph, graphColSize, returnSize, returnColumnSizes);
        stkSize--;
    }
}

int** allPathsSourceTarget(int** graph, int graphSize, int* graphColSize, int* returnSize, int** returnColumnSizes) {
    stkSize = 0;
    stk[stkSize++] = 0;
    ans = malloc(sizeof(int*) * 16384);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int) * 16384);
    dfs(0, graphSize - 1, graph, graphColSize, returnSize, returnColumnSizes);
    return ans;
}

3.力扣851

原题链接

851. 喧闹和富有

题目概述

有一组 n 个人作为实验对象,从 0 到 n - 1 编号,其中每个人都有不同数目的钱,以及不同程度的安静值(quietness)。为了方便起见,我们将编号为 x 的人简称为 "person x "。

给你一个数组 richer ,其中 richer[i] = [ai, bi] 表示 person ai 比 person bi 更有钱。另给你一个整数数组 quiet ,其中 quiet[i] 是 person i 的安静值。richer 中所给出的数据 逻辑自洽(也就是说,在 person x 比 person y 更有钱的同时,不会出现 person y 比 person x 更有钱的情况 )。

现在,返回一个整数数组 answer 作为答案,其中 answer[x] = y 的前提是,在所有拥有的钱肯定不少于 person x 的人中,person y 是最安静的人(也就是安静值 quiet[y] 最小的人)。

解题思路

这题在拿到的时候一点思路都没有,在看了一会题目给的示例最后在本子上写了一写,当成了并查集思考了一会,然后图画出来之后又看了一会,觉得怪怪的,看了一眼提示,原来是一道拓扑排序的题目,拓扑排序暂时还只是知道基本的思路,有些难以联系到问题中,这里就先记录一下题目吧,下个月的这个时候应该肯定能做出来了。

源码剖析


4.力扣959

原题链接

959. 由斜杠划分区域

题目概述

在由 1 x 1 方格组成的 n x n 网格 grid 中,每个 1 x 1 方块由 ‘/’、‘’ 或空格构成。这些字符会将方块划分为一些共边的区域。

给定网格 grid 表示为一个字符串数组,返回 区域的数量 。

请注意,反斜杠字符是转义的,因此 ‘’ 用 ‘\’ 表示。

解题思路

看完之后完全没有思路,先做记录吧

源码剖析


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值