Givenn
nodes labeled from0
ton - 1
and a list ofundirected
edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
Notice
You can assume that no duplicate edges will appear in edges. Since all edges areundirected
,[0, 1]
is the same as[1, 0]
and thus will not appear together in edges.
Example
Givenn = 5
andedges = [[0, 1], [0, 2], [0, 3], [1, 4]]
, return true.
Givenn = 5
andedges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
, return false.
合法树的条件是:1. 全部点都连在一起;2. 不能有环。边连边查是否有环(两个点已经connected就有了),最后还得check一下是否全部连在一齐。
Copy HashMap < Integer , DSNode > map = new HashMap <>();
public boolean validTree( int n , int [][] edges) {
if (n <= 0 || edges == null || ( edges . length == 0 && n == 1 )) {
return true ;
}
for ( int i = 0 ; i < n; i ++ ) {
makeSet(i) ;
}
for ( int [] pair : edges) {
boolean loopExist = connect(pair[ 0 ] , pair[ 1 ]) ;
if (loopExist) {
return false ;
}
}
// 看了一下九章的答案,其实可以直接判断,边数==点数-1
// 如果不等就证明有些点没连上,不用这样判断,囧
DSNode lastP = findSet( map . get( 0 )) ;
for ( int i = 1 ; i < n; i ++ ) {
DSNode curP = findSet( map . get(i)) ;
if (curP != lastP) {
return false ;
}
}
return true ;
}
private boolean connect( int a , int b) {
DSNode na = map . get (a);
DSNode nb = map . get (b);
DSNode nap = findSet(na) ;
DSNode nbp = findSet(nb) ;
if (nap == nbp) {
return true ;
}
if ( nap . rank >= nbp . rank ) {
nbp . parent = nap;
nap . rank += nbp . rank ;
nbp . rank = - 1 ;
} else {
nap . parent = nbp;
nbp . rank += nap . rank ;
nap . rank = - 1 ;
}
return false ;
}
private DSNode findSet( DSNode node) {
DSNode parent = node . parent ;
if (parent == node) {
return parent;
}
node . parent = findSet( node . parent ) ;
return node . parent ;
}
private void makeSet( int val) {
DSNode newNode = new DSNode(val) ;
newNode . parent = newNode;
newNode . rank = 1 ;
map . put (val , newNode);
}
}
class DSNode {
int val;
int rank;
DSNode parent;
public DSNode ( int v) {
val = v;
}
}
Copy // 再写一遍
Map < Integer , DSNode > map = new HashMap <>();
public boolean validTree( int n , int [][] edges) {
if (edges == null ) {
return false ;
}
if ( edges . length != n - 1 ) {
return false ;
}
for ( int i = 0 ; i < n; i ++ ) {
makeNode(i) ;
}
for ( int [] edge : edges) {
DSNode from = map . get (edge[ 0 ]);
DSNode to = map . get (edge[ 1 ]);
if ( ! connect(from , to) ) {
return false ;
}
}
return true ;
}
private boolean connect( DSNode n1 , DSNode n2) {
DSNode root1 = findSet(n1) ;
DSNode root2 = findSet(n2) ;
if (root1 == root2) {
return false ;
}
if ( root1 . rank > root2 . rank ) {
root2 . parent = root1;
root1 . rank += root2 . rank ;
root2 . rank = - 1 ;
} else {
root1 . parent = root2;
root2 . rank += root1 . rank ;
root1 . rank = - 1 ;
}
return true ;
}
private DSNode findSet( DSNode cur) {
DSNode curP = cur . parent ;
if (curP == cur) {
return cur;
}
cur . parent = findSet( cur . parent ) ;
return cur . parent ;
}
private void makeNode( int val) {
DSNode node = new DSNode(val) ;
node . parent = node;
map . put (val , node);
}
}
class DSNode {
int val;
DSNode parent;
int rank;
public DSNode ( int v) {
val = v;
rank = 1 ;
}
}