Leetcode刷题c++版-207课程表

法一:深度优先遍历,发现环

class Solution {
    
    

    typedef struct GraphNode{
    
    
        int val;
        vector<GraphNode* > Neighbors;
        int label;
    }GraphNode;
public:
    //判断是否存在环
    void judgeCircle(GraphNode* graph, vector<int>& visit,bool& circleMark){
    
    
        //指针为空,则返回
        if(!graph) return;
        //找到环了,返回
        if(!circleMark) return;
        //没有neighbor,返回
        if((graph->Neighbors).size() == 0) {
    
    
            //cout<< "visiting "<<graph->label<<endl;
            visit[graph->label] = 1;
            return;
        }
        for(int i=0; i< (graph->Neighbors).size(); i++){
    
    
            //如果neighbor未访问过
            if( visit[(graph->Neighbors)[i]->label] == -1){
    
    
                visit[(graph->Neighbors)[i]->label] = 0;//状态改为正在访问
                judgeCircle((graph->Neighbors)[i], visit, circleMark);
                visit[(graph->Neighbors)[i]->label] = 1;
            }
            //如果neighbor是正在访问的节点
            else if(visit[(graph->Neighbors)[i]->label] == 0){
    
    
                circleMark = false;
                return;
            }
            visit[(graph->Neighbors)[i]->label] = 1;
           // }
            
        }

    }

    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
    
    
        vector<GraphNode*> graph;
        vector<int> visit;//3种状态,-1为未访问,0为正在访问,1为访问完毕
        bool circleMark = true;
        for(int i = 0; i< numCourses; i++){
    
    
            GraphNode* p = new GraphNode;
            p->label = i;
            graph.push_back(p);
            visit.push_back(-1);
        }
        for(int i = 0; i< prerequisites.size(); i++){
    
    
            graph[prerequisites[i][0]]->label = prerequisites[i][0];
            //cout<<  graph[prerequisites[i][0]]->label<<endl;
            graph[prerequisites[i][0]]->Neighbors.push_back(graph[prerequisites[i][1]]) ;
        }

        for(int i = 0; i< graph.size(); i++){
    
    
            
            visit[graph[i]->label] = 0;
            //cout<< "1";
            judgeCircle(graph[i], visit, circleMark);
            visit[graph[i]->label] = 1;
            if(!circleMark) return false;
        }return true;
    }
};

在这里插入图片描述

法二:利用拓扑排序,遍历所有入度为0的点,看是否能遍历完所有的点

class Solution {
    
    

    typedef struct GraphNode{
    
    
        int val;
        vector<GraphNode* > Neighbors;
        int label;
    }GraphNode;
public:
    //利用拓扑排序
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
    
    
        //if(prerequisites.size() <= 1 || numCourses <= 1) return true;
        vector<GraphNode*> graph;
        vector<int> depth;
        queue<GraphNode*> visit;

        for(int i = 0; i<numCourses; i++){
    
    
        //初始化图和depth数组
            GraphNode* p = new GraphNode;
            p->label = i;
            graph.push_back(p);
            depth.push_back(0);
        }

        for(int i = 0; i< prerequisites.size(); i++){
    
    
        //例如【1,0】,则说明学1之前需要学完0,则0的入度不需要改变,1号点的入度需要加一
            graph[prerequisites[i][1]]->Neighbors.push_back(graph[prerequisites[i][0]]);
            depth[prerequisites[i][0]]++;
        }

        while(true){
    
    
        	//每次遍历所有的点,将入度为0的点加入到队列中,直到没有点可加入为止
            for(int i = 0; i< numCourses; i++){
    
    
                if(depth[i]==0){
    
    
                    visit.push(graph[i]);
                }
            }

            if(visit.size() == 0) {
    
    
                break;
            }

            while(visit.size()){
    
    
            //访问队列中的每一个节点,将他们的邻居入度减一
                for(int i = 0; i< visit.front()->Neighbors.size(); i++){
    
    
                    depth[visit.front()->Neighbors[i]->label] --;
                }
                //已经访问过的节点depth置为-1
                depth[visit.front()->label] = -1;
                visit.pop();
                
            }

        }

        for(int i = 0; i< numCourses; i++){
    
    
        		//如果还有未访问的点则说明存在环
                if(depth[i]>0){
    
    
                   return false;
                }
        }
        return true;
       
    }
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44343355/article/details/128962174
今日推荐