下面是DFS Medium级别题目的后5道,列表目录:
#1.Convert Sorted Array to Binary Search Tree
ref
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
将一个升序数组转换成一个高度平衡的二分查找树BST,即AVL树 ,递归方法很easy.
TreeNode * BST ( vector < int > & num , int start , int end )
{
if ( start > end )
{
return NULL ;
}
int mid = ( start + end ) / 2 ;
TreeNode * root = new TreeNode ( num [ mid ]);
root -> left = BST ( num , start , mid - 1 );
root -> right = BST ( num , mid + 1 , end );
}
TreeNode * sortedArrayToBST ( vector < int > & num )
{
if ( num . size () < 1 )
{
return NULL ;
}
return BST ( num , 0 , num . size () - 1 );
}
#2.Convert Sorted List to Binary Search Tree
ref
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
###方法一
将有序链表转换成有序数组,再按照Convert Sorted Array to Binary Search Tree 方法来建BST树。
缺点就是消耗了O(n)的额外空间,下策。
TreeNode * buildTree ( vector < int > & arr , int si , int ei )
{
if ( si > ei )
{
return NULL ;
}
else
{
int mi = ( si + ei ) / 2 ;
TreeNode * node = new TreeNode ( arr [ mi ]);
node -> left = buildTree ( arr , si , mi - 1 );
node -> right = buildTree ( arr , mi + 1 , ei );
}
}
TreeNode * sortedListToBST ( ListNode * head )
{
vector < int > arr ;
for ( ListNode * p = head ; p ; p = p -> next )
{
arr . push_back ( p -> val );
}
TreeNode * root = buildTree ( arr , 0 , arr . size () - 1 );
return root ;
}
###方法二
我们多花点时间来查找链表的中间结点吧,时间复杂度还是O(n),空间复杂度降到O(1).
TreeNode * buildTree ( ListNode * head , int len )
{
if ( len < 1 )
{
return NULL ;
}
else
{
int mid = 0 ;
ListNode * p ;
for ( p = head ; mid < len / 2 ; p = p -> next , mid ++ );
TreeNode * node = new TreeNode ( p -> val );
node -> left = buildTree ( head , mid );
node -> right = buildTree ( p -> next , len - mid - 1 );
}
}
TreeNode * sortedListToBST ( ListNode * head )
{
int n = 0 ;
for ( ListNode * p = head ; p ; p = p -> next , n ++ );
return buildTree ( head , n );
}
#3.Construct Binary Tree from Preorder and Inorder Traversal
ref
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
根据先根遍历可以确定根结点,有了根结点,就可以分割中根遍历序列,左边是左子树,右边是右子树。所以题目中的假设前提很重要,没有重复的结点!
TreeNode * build ( vector < int > & preorder , int psi , int pei ,
vector < int > & inorder , int isi , int iei )
{
if ( psi > pei || isi > iei )
{
return NULL ;
}
int imi = isi ;
for ( imi ; imi <= iei && preorder [ psi ] != inorder [ imi ]; imi ++ );
assert ( imi <= iei );
int psep = imi - isi + psi ;
TreeNode * root = new TreeNode ( preorder [ psi ]);
root -> left = build ( preorder , psi + 1 , psep , inorder , isi , imi - 1 );
root -> right = build ( preorder , psep + 1 , pei , inorder , imi + 1 , iei );
return root ;
}
TreeNode * buildTree ( vector < int > & preorder , vector < int > & inorder )
{
if ( preorder . size () < 1 )
{
return NULL ;
}
return build ( preorder , 0 , preorder . size () - 1 , inorder , 0 , inorder . size () - 1 );
}
#4.Construct Binary Tree from Inorder and Postorder Traversal
ref
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
和前一题目 类似,后根遍历序列用来确定根结点,由这个根结点划分中根遍历序列,从而确立左右子树。
TreeNode * build ( vector < int > & inorder , int isi , int iei ,
vector < int > & postorder , int psi , int pei )
{
if ( psi > pei || isi > iei )
{
return NULL ;
}
int imi = isi ;
for ( imi ; imi <= iei && postorder [ pei ] != inorder [ imi ]; imi ++ );
assert ( imi <= iei );
int psep = imi - isi + psi - 1 ;
TreeNode * root = new TreeNode ( postorder [ pei ]);
root -> left = build ( inorder , isi , imi - 1 , postorder , psi , psep );
root -> right = build ( inorder , imi + 1 , iei , postorder , psep + 1 , pei - 1 );
return root ;
}
TreeNode * buildTree ( vector < int > & inorder , vector < int > & postorder )
{
if ( inorder . size () < 1 )
{
return NULL ;
}
return build ( inorder , 0 , inorder . size () - 1 , postorder , 0 , postorder . size () - 1 );
}
#5.Clone Graph
ref
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
OJ’s undirected graph serialization:
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as separated by #.
First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1
/ \
/ \
0 --- 2
/ \
\_/
邻接表法表示的图结构,每个node的标签是唯一的。主要的问题是避免重复clone结点。
clone过程分两步
创建新节点,BFS图,用一个映射表map<int, UndirectedGraphNode*> gmap;记录创建过的结点;
连接新节点,BFS图,用set visited;记录连接过的顶点标签;
struct UndirectedGraphNode {
int label ;
vector < UndirectedGraphNode *> neighbors ;
UndirectedGraphNode ( int x ) : label ( x ) {};
};
class Solution {
public:
UndirectedGraphNode * cloneGraph ( UndirectedGraphNode * node ) {
//1. 遍历所有顶点,并创建新节点
queue < UndirectedGraphNode *> gqueue ;
map < int , UndirectedGraphNode *> gmap ;
UndirectedGraphNode * p ;
if ( node )
{
gqueue . push ( node );
}
while ( ! gqueue . empty ())
{
p = gqueue . front ();
gqueue . pop ();
if ( gmap . find ( p -> label ) != gmap . end ())
{ //already exists
continue ;
}
gmap [ p -> label ] = new UndirectedGraphNode ( p -> label );
for ( int i = 0 ; i < p -> neighbors . size (); i ++ )
{
gqueue . push ( p -> neighbors [ i ]);
}
}
//2. 将gmap中的节点连接起来
set < int > visited ;
if ( node )
{
gqueue . push ( node );
}
while ( ! gqueue . empty ())
{
p = gqueue . front ();
gqueue . pop ();
if ( visited . find ( p -> label ) != visited . end ())
{ //already visited
continue ;
}
visited . insert ( p -> label );
for ( int i = 0 ; i < p -> neighbors . size (); i ++ )
{
gqueue . push ( p -> neighbors [ i ]);
gmap [ p -> label ] -> neighbors . push_back ( gmap [ p -> neighbors [ i ] -> label ]);
}
}
//
if ( node )
{
return gmap [ node -> label ];
}
return node ;
}
};
###完
到此,LeetCode Esay和Medium级别的DFS类型题目已经完了,还剩下3道Hard。
留下评论