給你一個?n
?個節點的?有向圖?,節點編號為?0
?到?n - 1
?,每個節點?至多?有一條出邊。
有向圖用大小為?n
?下標從?0?開始的數組?edges
?表示,表示節點?i
?有一條有向邊指向?edges[i]
?。如果節點?i
?沒有出邊,那么?edges[i] == -1
?。
同時給你兩個節點?node1
?和?node2
?。
請你返回一個從?node1
?和?node2
?都能到達節點的編號,使節點?node1
?和節點?node2
?到這個節點的距離?較大值最小化。如果有多個答案,請返回?最小?的節點編號。如果答案不存在,返回?-1
?。
注意?edges
?可能包含環。
示例 1:
輸入:edges = [2,2,3,-1], node1 = 0, node2 = 1 輸出:2 解釋:從節點 0 到節點 2 的距離為 1 ,從節點 1 到節點 2 的距離為 1 。 兩個距離的較大值為 1 。我們無法得到一個比 1 更小的較大值,所以我們返回節點 2 。
示例 2:
輸入:edges = [1,2,-1], node1 = 0, node2 = 2 輸出:2 解釋:節點 0 到節點 2 的距離為 2 ,節點 2 到它自己的距離為 0 。 兩個距離的較大值為 2 。我們無法得到一個比 2 更小的較大值,所以我們返回節點 2 。
提示:
n == edges.length
2 <= n <= 10^5
-1 <= edges[i] < n
edges[i] != i
0 <= node1, node2 < n
分析:題目提到每個點至多有一條出邊,可以從某個點出發,一直沿著出邊遍歷,得到這個點可以到達的所有點,以及對應的距離。之后對比 node1 和 node2 能達到的點和距離,找到符合要求的點即可。
typedef struct node
{int pos,dis;
}node;int closestMeetingNode(int* edges, int edgesSize, int node1, int node2) {int t=1;int len1[edgesSize+5],len2[edgesSize+5],flag1[edgesSize+5],flag2[edgesSize+5];node num1[edgesSize+5],num2[edgesSize+5];memset(flag1,0,sizeof(flag1));memset(flag2,0,sizeof(flag2));flag1[node1]=1,num1[node1].dis=0,num1[node1].pos=node1;for(int i=node1;i<edgesSize;i=edges[i]){if(i==-1||edges[i]==-1)break;if(!flag1[edges[i]])num1[edges[i]].dis=t,num1[edges[i]].pos=edges[i],flag1[edges[i]]=1,t++;else break;}t=1;flag2[node2]=1,num2[node2].dis=0,num2[node2].pos=node2;for(int i=node2;i<edgesSize;i=edges[i]){if(i==-1||edges[i]==-1)break;if(!flag2[edges[i]])num2[edges[i]].dis=t,num2[edges[i]].pos=edges[i],flag2[edges[i]]=1,t++;else break;}int ans=-1,index=-1;for(int i=0;i<edgesSize;++i){if(flag1[i]&&flag1[i]==flag2[i]){if(ans==-1||ans>fmax(num1[i].dis,num2[i].dis))ans=fmax(num1[i].dis,num2[i].dis),index=num1[i].pos;else if(ans==fmax(num1[i].dis,num2[i].dis))index=fmin(index,num1[i].pos);}}return index;
}