节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
提示:
节点数量n在[0, 1e5]范围内。
节点编号大于等于 0 小于 n。
图中可能存在自环和平行边。
思路: 判断两点之间是否连通,用DFS或者BFS,用栈实现DFS,用队列实现BFS。我不喜欢递归,递归要迭代,我脑子里建不起迭代的过程图。
用栈实现DFS伪码:
栈初始化,并让起始顶点入栈,起始顶点改为已访问
栈不为空:
2.1 取栈顶元素
2.2 栈顶元素的邻接点 n n n,并且 n n n没有被访问,则:将邻接点 n n n标记为已访问,并且让点 n n n进栈
2.3 如果2.2没有邻接点进展,需要将当前结点退栈。
class Solution {
public:
vector> construct_map(int n, vector>& graph){
vector> map(n);
int row = graph.size();
for(int i = 0;i>& graph, int start, int target) {
if(start == target) return true;
vector> map = construct_map(n, graph);
//
vector visit(n, 0);
stack S;
S.push(start);
visit[start] = 1;
while(!S.empty()){
int tmp = S.top();
int len = map[tmp].size();
bool flag = false;
for(int i=0;i>& graph, int start, int target) {
if(start == target) return true;
vector> map = construct_map(n, graph);
//
vector visit(n, 0);
queue Q;
Q.push(start);
visit[start] = 1;
while(!Q.empty()){
int tmp = Q.front();
int len = map[tmp].size();
bool flag = false;
for(int i=0;i
给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。
思路: 二分图染色法判定二分图。对一个无向图,要给每个图上顶点进行染色,最多用两种染色,任意相邻的顶点染色不同,如果可以对图进行染色,那就说明是一个二分图。题目中没说给给定的图是连通图,所以还需要考虑到非连通的图。
class Solution {
public:
bool isBipartite(vector>& graph) {
int n = graph.size();
stack S;
vector vis(n, 0);
vector color(n, -1);
// 考虑图非连通
for(int i=0;i
现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?
思路: 判断是否是有向无环图DAG。DAG才有拓扑排序,非DAG没有拓扑排序。使用顶点入度+BFS,判断是否能够拓扑排序。
class Solution {
public:
bool canFinish(int numCourses, vector>& prerequisites) {
int row = prerequisites.size();
vector degree(numCourses, 0);
for(int i=0;i Q;
for(int i=0;i
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
思路: 假设网格的大小为 n ∗ m n*m n∗m,规定只能向下或者向右,从网格的左上角到右下角需要走 n + m − 2 n+m-2 n+m−2步,其中向下走了 n − 1 n-1 n−1,向右走了 m − 1 m-1 m−1,所以总的路径数就是 C m + n − 2 m i n ( n , m ) − 1 C_{m+n-2}^{min(n,m)-1} Cm+n−2min(n,m)−1
求组合数用到了 C n m = C n − 1 m − 1 + C n − 1 m C_{n}^{m} = C_{n-1}^{m-1} + C_{n-1}^{m} Cnm=Cn−1m−1+Cn−1m
class Solution {
public:
int uniquePaths(int m, int n) {
int total = m + n - 2;
int select = min(m, n) - 1;
return combination(total, select);
}
int combination(int total, int select){
if(total==select||select==0){
return 1;
}else if(select == 1){
return total;
}
return combination(total-1, select-1) + combination(total-1, select);
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。