BFS 1 - Graph Traversal
BFS in Graph vs. BFS in Tree: 无向图 vs. 有向图; 需要标记数组 vs. 不需要
时间复杂度:O(m + n),m是边数,n是点数
Given a boolean 2D matrix, 0 is represented as the sea, 1 is represented as the island. If two 1 is adjacent, we consider them in the same island. We only consider up/down/left/right adjacent.
Find the number of islands.
void bfs ( vector < vector < bool >> & grid , int starti , int startj ) {
queue < pair < int , int >> q ;
q . push ( make_pair ( starti , startj ));
int neibor [ 4 ][ 2 ] { - 1 , 0 , 1 , 0 , 0 , - 1 , 0 , 1 };
while ( ! q . empty ()) {
auto tmp = q . front ();
q . pop ();
grid [ tmp . first ][ tmp . second ] = 0 ; // 记得标记
for ( int i = 0 ; i < 4 ; i ++ ) {
int nextx = tmp . first + neibor [ i ][ 0 ];
int nexty = tmp . second + neibor [ i ][ 1 ];
// 不要忘了先判断边界,否则会越界访问grid
if ( nextx >= 0 && nextx < grid . size () && nexty >= 0 && nexty < grid [ 0 ]. size () && grid [ nextx ][ nexty ] == 1 ) {
grid [ nextx ][ nexty ] = 0 ; // !!放的时候就标记,记得标记,会优化时间!防止重复进来
q . push ( make_pair ( nextx , nexty ));
}
}
}
}
int numIslands ( vector < vector < bool >> & grid ) {
// 1. 找这个矩阵里的第一个1,放到queue里
// 2. bfs开始找,然后弄成0
// 3. 重复上述2步,直到矩阵没有1
if ( grid . size () == 0 ) return 0 ;
if ( grid [ 0 ]. size () == 0 ) return 0 ;
int num = 0 , rows = grid . size (), cols = grid [ 0 ]. size ();
int num_island = 0 ;
for ( int i = 0 ; i < rows ; i ++ ) {
for ( int j = 0 ; j < cols ; j ++ ) {
if ( grid [ i ][ j ] == 1 ) {
num_island ++ ;
bfs ( grid , i , j );
}
}
}
return num_island ;
}
Given a undirected graph, a node and a target, return the nearest node to given node which value of it is target, return NULL if you can't find.
UndirectedGraphNode * searchNode ( vector < UndirectedGraphNode *>& graph ,
map < UndirectedGraphNode * , int >& values ,
UndirectedGraphNode * node ,
int target ) {
if ( graph . size () == 0 ) return NULL ;
queue < UndirectedGraphNode *> q ;
unordered_set < UndirectedGraphNode *> visited ;
q . push ( node );
visited . insert ( node );
while ( ! q . empty ()) {
UndirectedGraphNode * cur = q . front ();
q . pop ();
if ( values [ cur ] == target ) return cur ; // 弹出的时候,判断结果
for ( auto n : cur -> neighbors ) {
if ( visited . find ( n ) != visited . end ()) continue ;
q . push ( n );
visited . insert ( n ); // 放的时候就标记
}
}
return NULL ;
}
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each
edge is a pair of nodes), write a function to check whether these edges make up
a valid tree.
You can assume that no duplicate edges will appear in edges. Since all edges are
undirected, [0, 1] is the same as [1, 0] and thus will not appear together in
edges.
Example
Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.
Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.
bool validTree ( int n , vector < vector < int >>& edges ) {
int nedges = edges . size ();
// 边数对,且从任意一点,能遍历到所有节点
if ( nedges != n - 1 ) return false ;
set < int > nodes ;
unordered_map < int , vector < int >> orders ;
for ( int i = 0 ; i < nedges ; i ++ ) {
orders [ edges [ i ][ 0 ]]. push_back ( edges [ i ][ 1 ]);
orders [ edges [ i ][ 1 ]]. push_back ( edges [ i ][ 0 ]);
}
queue < int > q ;
q . push ( 0 );
nodes . insert ( 0 ); // just pick one to start
while ( ! q . empty ()) {
int cur = q . front ();
q . pop ();
for ( auto i : orders [ cur ]) {
// !! nodes可以充当visited的角色,不需要再开一个visited了
if ( nodes . find ( i ) != nodes . end ()) continue ;
nodes . insert ( i );
q . push ( i );
}
}
return nodes . size () == n ;
}
Union-Find algorithm
bool validTree ( int n , vector < vector < int >>& edges ) {
vector < int > root ( n , - 1 );
for ( int i = 0 ; i < edges . size (); i ++ ) {
int root1 = find ( root , edges [ i ][ 0 ]);
int root2 = find ( root , edges [ i ][ 1 ]);
if ( root1 == root2 ) return false ;
root [ root1 ] = root2 ;
}
return edges . size () == n - 1 ;
}
int find ( vector < int >& root , int e ) {
if ( root [ e ] == - 1 )
return e ;
else
return root [ e ] = find ( root , root [ e ]);
}
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
UndirectedGraphNode * cloneGraph ( UndirectedGraphNode * node ) {
if ( node == NULL ) return NULL ;
// 1. BFS: Get list of all the nodes
// 2. Copy these nodes, and get hash map: old->new
unordered_map < UndirectedGraphNode * , UndirectedGraphNode *> corres ;
unordered_set < UndirectedGraphNode *> visited ;
queue < UndirectedGraphNode *> q ;
q . push ( node );
visited . insert ( node ); // 图的BFS一定注意有visited
while ( ! q . empty ()) {
UndirectedGraphNode * cur = q . front ();
corres [ cur ] = new UndirectedGraphNode ( cur -> label );
q . pop ();
for ( auto i : cur -> neighbors ) {
if ( visited . find ( i ) != visited . end ()) continue ;
q . push ( i );
visited . insert ( i );
}
}
// 3. Copy the edges.
for ( auto i : corres ) {
for ( auto j : i . first -> neighbors ) {
i . second -> neighbors . push_back ( corres [ j ]); // push corres[j]
}
}
return corres [ node ];
}