leetcode:802. 找到最終的安全狀態(圖)

題目:

在這裏插入圖片描述

分析:

思路很簡單,就是找圖中的環。
題解思路:
反向的拓撲排序
在這裏插入圖片描述
一個圖中,如果沒有入度爲0的點,那麼所有的點都在圖上。

代碼1:超時:提醒自己:圖,不要總是想着用最基本的鄰接的那個二維矩陣:

 vector<vector<int> > g;
 int A[g.size()][g.size()];//A[i][j]   i->j
 memset(A,0,sizeof(A));
 for(int i=0;i<g.size();i++)
 {
  for(int j=0;j<g[i].size();j++)
  {
   A[g[i][j]][i]=1;//箭頭反向。 
  }
 }
 vector<int> v;
 set<int> s; 
 while(1)
 {
  //入度爲0的點,即列上全爲0。 
  int loca=-1;
  for(int i=0;i<g.size();i++)
  {
   int ok=1;
   for(int j=0;j<g.size();j++)
   {
    if(A[j][i]==1){
     ok=0;
     break;
    }
   }
   if(ok==0) continue;
   //i列全爲0了
   if(s.count(i)==1) continue;
   //1 
   s.insert(i);
   v.push_back(i); 
   //出度撤銷
   for(int k=0;k<g.size();k++)
   A[i][k]=0; 
   loca=1;
   break;
  }
  if(loca==-1) break;
 }
 sort(v.begin(),v.end());
 return v;

代碼2:尋找上面複雜的原因,每次找到入度爲0的點。優化後,還是超時,哎

vector<vector<int> > g;
 queue<int> q;
 vector<int> v;
 map<int,int> m; 
 vector<vector<int> > rg(g.size(),vector<int>);
 //反向 
 for(int i=0;i<g.size();i++)
 {
  for(int j=0;j<g[i].size();j++)
  {
   g[g[i][j]].push_back(i);
  }
  //尋找g中出度爲0的點。即g【i】爲空。
  if(g.size()==0) 
  {
   q.push(i); 
  }
  
 }
 //尋找g中出度爲0的點。即g【i】爲空。 
 while(1)
 {
  if(q.size()==0) break;
  int c=q.front();
  q.pop();
  //安全嗎? 用g 
  int ok=1;
  for(int i=0;i<g[c].size();i++)
  {
   if(m[g[c][i]]=0) {
    ok=0;
    break;
   }
  }
  if(ok)
  {
   m[c]=1;
   v.push_back(c);
   //加入新的可能的   用rg
   for(int i=0;i<rg[c].size();i++)
   {
    if(m[rg[c][i]]) continue;
    queue<int> qq=q;
    int cc=1;
    while(!qq.empty())
    {
     if(rg[c][i]==qq.front())
     {
      cc=0;
      break;
     }
     qq.pop();
    }
    if(cc) q.push(rg[c][i]);
    } 
   } 
 }
 sort(v.begin(),v.end());
 return v;

再看題解,直接用數組記錄了度數:

class Solution {
public:
    vector<int> eventualSafeNodes(vector<vector<int>>& g) {
 queue<int> q;
 vector<int> v;
 map<int,int> m; 
 vector<vector<int> > rg(g.size(),vector<int>());
 int A[g.size()];
 memset(A,0,sizeof(A));
 //反向 
 for(int i=0;i<g.size();i++)
 {
  for(int j=0;j<g[i].size();j++)
  {
   rg[g[i][j]].push_back(i);
  }
  //尋找g中出度爲0的點。即g【i】爲空。
  if(g[i].size()==0) 
  {
   q.push(i); 
  }
  A[i]=g[i].size();
 }
 //尋找g中出度爲0的點。即g【i】爲空。 
    cout<<q.size();
 while(1)
 {
  if(q.size()==0) break;
  int c=q.front();
  q.pop();
  v.push_back(c);
  for(int i=0;i<rg[c].size();i++)
  {
   A[rg[c][i]]--;
   if(A[rg[c][i]]==0) q.push(rg[c][i]);
  }
 }
 sort(v.begin(),v.end());
 return v;
    }
};

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章