本篇博客是关于七月算法 ,曹鹏老师所讲的关于图论部分的习题,加上自己的补充与笔记!

//给定二叉树的前序和中序遍历,构造二叉树  leetcode105、106 

//二叉树每个节点有一个整数,返回和最大的路径   leetcode124

//二叉树最小深度 ,注意空子树      leetcode111

//判断二叉树平衡 leetcode110 

//最大深度 leetcode104 

//判断相同 leetcode100

//判断对称 leetcode101 

//判断二叉搜索树 leetcode98

//二叉树转换为链表 leetcode114

//链表转换为平衡二叉树 leetcode 109 

//将有序数组转换为平衡二叉树  leetcode108

//复制一个有向图 (邻接表存储) leetcode133 


//给定二叉树的前序和中序遍历,构造二叉树  leetcode105、106 
class solution {
	TreeNode *help(vector<int> &preorder,vector<int> &inorder,int fromp,int fromi,int length) {
		if(length==0) {
			return 0;
		}
		TreeNode *root=new TreeNode(preorder[fromp]);
		int i;
		for(i=fromi;inorder[i]!=preorder[fromp];++i)
			;
		root->left=help(preorder,inorder,fromp+1,fromi,i-fromi);
		root->right=help(preorder,inorder,fromp+1+i-fromi,i+1,length-1-i+fromi);
		return root;
	}
	
	TreeNode *builder(vector<int> &preorder,vector<int> &inorder) {
		return help(preorder,inorder,0,0,preorder.size());
	}
};

 

//二叉树每个节点有一个整数,返回和最大的路径   leetcode124
class solution{
	int help(TreeNode *root,int &m) {
		if(root==0)	{
			return 0;
		}
		int left=help(root->left,m);
		int right=help(root->right,m);
		int ret=max(max(left,right),0) + root->val;
		m=max(max(m,ret),left+right+root->val);
		return ret;
	}
	
	int maxPathSum(TreeNode *root) {
		if(root==0) {
			return 0;
		}
		int result=root->val;
		help(root,result);
		return result;
	}
};



//二叉树最小深度 ,注意空子树      leetcode111
class solution {
	int minDepth(TreeNode *root) {
		if(root==0) {
			return 0;
		}
		if(root->left) {
			if(root->right) {
				return min(mindepth(root->left),minDepth(root->right))+1;
			}
			else {
				return minDepth(root->right)+1;
			}
		}
		else if(root->right) {
			return minDepth(root->right)+1;
		}
		else {
			return 1;
		}
	}
};
 
//判断二叉树平衡 leetcode110 
class soulution {
	bool help(TreeNode *root,int &height) {
		if(root==0) {
			height=0;
			return true;
		}
		
		int height1,height2;
		if(!help(root->left,height1)) {
			return false;
		}
		if(!help(root->right,height2)) {
			return false;
		}
		height=max(height1,height2)+1;
		return (height1>=height2-1) && (height1<=height2+1);
	}
	
	bool isBalance(TreeNode *root) {
		int height;
		return help(root,height);
	}
};

class Solution {
public:
	int dept(TreeNode *root){    //返回子树深度
	if(root == NULL)
		return 0;
	if(root -> left == NULL && root ->right == NULL)
		return 1;
	return max(dept(root->left),dept(root->right)) + 1;
}

	bool isBalanced(TreeNode* root) {  //递归判断是否为平衡树
	if(root == NULL)
		return true;
	int x = dept(root->left) - dept(root->right);
	if(x > 1 || x < -1)
		return false;
	else
		return isBalanced(root->left) && isBalanced(root->right); 
	}
}; 

//最大深度 leetcode104 
class solution {
	public:
		int maxDepth(TreeNode *root) {
			return root?(max(maxDepth(root->left),maxDepth(root->right))+1):0;
		}
};


//采用DFS的思想
int maxDepth(TreeNode *root)
{
    if (NULL == root)
        return 0;
    int l = maxDepth(root->left);
    int r = maxDepth(root->right);

    return l > r ? l + 1:r+1;
    //以上这两种方式有一种更简便的方法
    //return 1 + max(maxDepth(root->left), maxDepth(root->right));
}

//判断相同 leetcode100
class solution {
	bool isSameTree(TreeNode *p,TreeNode *q) {
		if(p==0) {
			return q==0;
		}
		if(q==0) {
			return false;
		}
		return (p->val == q->val) && isSameTree(p->left,q->left) &&isSameTree(p->right,q->right);
	}
}; 


class Solution {
public:
    bool isSameTree(TreeNode *p, TreeNode *q) {
        return (p == NULL && q == NULL) ||
            ((p != NULL && q != NULL && p->val == q->val) &&
            (isSameTree(p->left, q->left) && isSameTree(p->right, q->right)));
    }
};

//判断对称 leetcode101 
class solution {
	public:
	bool help(TreeNode *root1,TreeNode *root2) {
		if(root1==0) {
			return root2==0;
		} 
		if(root2==0) {
			return false;
		}
		return (root1->bal==root2->val) && help(root1->left,root2->right) &&help(root1->right,root2->left);
	} 
	
	bool isSymmetric(TreeNode *root) {
		if(root==0) {
			return true;
		}
		return help(root->left,root->right);
	}
};

//判断二叉搜索树 leetcode98
class solution {
	public:
	bool help(TreeNode *root,bool &first,int &last) {
		if(root==0) {
			return true;
		}
		if(!help(root->left,first,last)) {
			return false; 
		} 
		if(first) {
			first=false;
			last=root->val;
		}
		else if(last>= root->val) {
			return false;
		}
		last=root->val;
		return help(root->right,first,last);
	}
	
	bool isValidBST(TreeNode *root) {
		bool mark=true;
		int val=0;
		return help(root,mark,val);
	}
};
 
//思路二: 先将该树中序遍历一遍,按中序遍历的顺序保存到一个vector中,然后判断vector中的顺序即可。
class Solution {
public:
    void inOrder(TreeNode *root){
        if(root->left != NULL) inOrder(root->left);
        v.push_back(root->val);
        if(root->right != NULL) inOrder(root->right);
        
    }
    bool isValidBST(TreeNode *root) {
        if(root == NULL) return true;
        inOrder(root);
        for(int i = 1; i< v.size(); i++)
            if(v[i] <= v[i-1]) return false;
        return true;
        
    }
private:
    vector<int> v;    
        
};


//二叉树转换为链表 leetcode114 (没明白) 
class solution {
	public:
		void help(TreeNode *&root,TreeNode *&last) {
			last=root;
			if(root==0) {
				return ;
			}
			TreeNode *maylast,*temp=root->right;
			help(root->left,maylast);
			if(maylast) {
				last=maylast;
				last->right=temp;
				root->right=root->left;
				root->left=0;
			}
			help(temp,maylast);
			if(maylast) {
				last=maylast;
			}
		}	
			
		void flatten(TreeNode *root) {
			TreeNode *last;
			help(root,last);
		}
}; 

//因为节点的右指针用作链表指针,所以说二叉树在转换为链表时,节点右指针可能会被修改 
class solution {
	public:	
		void flatten(TreeNode *root) {
			if(root==NULL)	{
				return ;
			}
			TreeNode *pre=NULL;
			flatten(root,pre);
		}
	private:
		void flatten(TreeNode *node,TreeNode *&pre) {
			if(node==NULL)	{
				return;
			}
			TreeNode *rightNode=node->right;//记住右子节点 
			TreeNode *leftNode= node->left;//记住左子节点 
			if(pre!=NULL) {//转换为链表 
				pre->right=node;
				pre->left=NULL;
			}
			pre=node;
			if(leftNode) {//左子树 
				flatten(leftNode,pre);
			}
			if(rightNode) {//右子树 
				flatten(rightNode,pre);
			}
		}
};  


//链表转换为平衡二叉树 leetcode 109 (不是很明白)
class solution {
public:
	TreeNode *help(ListNode *head,int length) {
		if(length==0) {
			return 0;
		}
		ListNode *now=head;
		for(int i=(length-1)>>1;i;--i) {
			now=now->next;
		}
		TreeNode *root=new TreeNode(now-val);
		root->left=help(head,(length-1)>>1);
		root->right=help(now->nextmlength>>1);
		return root;
	}
	
	TreeNode * sortedListToBST(ListNode *head) {
		ListNode * temp=head;
		int length;
		for(length=0;temp;temp=temp->next,++length)
			;
		return help(head,length);
	}
};
 
//思路二: https://siddontang.gitbooks.io/leetcode-solution/content/tree/convert_sorted_listarray_to_binary_search_tree.html
//对于二叉树来说,左子树小于根节点,而右子树大于根结点。所以需要找到链表的中间节点,这个就是根节点。
//链表的左半部分就是左子树,而右半部分是右子树,继续递归处理相应的左右部分,就可以构造对应的二叉树了。
//难点在于如何找到链表的中间节点,可以通过fast、slow指针来解决,fast走两步,slow每次走一步,fast走到尾,slow就是中间节点。 
 
class solution {
public:
	TreeNode *sortedListToBST(ListNode *head) {
		return build(head,NULL);
	}
	TreeNode *build(ListNode * start,ListNode * end) {
		if(start==end) {
			return NULL;
		}
		ListNode *fast=start;
		ListNode *slow=start;
		while(fast !=end &&fast->next!=end) {
			slow=slow->next;
			fast=fat->next->next;
		}
		TreeNode *node=new TreeNode(slow->val);
		node->left=build(start,slow);
		node->right=build(slow->next,end);
		
		return node;
	}
};

//将有序数组转换为平衡二叉树  leetcode108
class solution {
public:
	TreeNode *sortedArrayToBST(vector<int> &num) {
		return build(num,0,num.size());
	}
	TreeNode* build(vector<int>&num,int start,int end) {
		if(start>=end) {
			return NULL;
		}
		int mid=start+(end-start)/2;
		TreeNode *node=new TreeNode(num[mid]);
		node->left=build(num,start,mid);
		node->right=build(num,mid+1,end);
	}
};

//复制一个有向图 (邻接表存储) leetcode133  不太明白 
class solution{
public:
	UndirectedGraphNode *dfs(const UndirectedGraphNode *node,map<int,UndirectedGraphNode*> &have) {
		map<int,UndirectedGraphNode*>::iterator t=have.find(node->label);
		if(t==have.end()) {
			UndirectedGraphNode *newnode=new UndirectedGraphNode(node->label);
			have.insert(make_pair(node->label,newnode));
			for(int i=0;i<node->neighbors.size();++i) {
				newnode->neighbors.push_back(dfs(node->neighbors[i],have));
			}
			return newnode;
		}
	}
		
	UndirectedGraphNode *cloneGraph(undirectedGraphNode *node) {
		map<int,UndirectedGraphNode *>have;
		if(node==0) {
			return 0;
		}
		return dfs(node,have);
	}	
}; 


//解法二:递归深度优先遍历DFS 
class Solution {
public:
    map<UndirectedGraphNode *, UndirectedGraphNode *> m;
    
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) 
    {
        if(node == NULL)
            return NULL;
        
        if(m.find(node) != m.end())   //if node is visited, just return the recorded nodeClone
            return m[node];
            
        UndirectedGraphNode *nodeClone = new UndirectedGraphNode(node->label);
        m[node] = nodeClone;
        for(int st = 0; st < node->neighbors.size(); st ++)
        {
            UndirectedGraphNode *temp = cloneGraph(node->neighbors[st]);
            if(temp != NULL)
                nodeClone->neighbors.push_back(temp);
        }
        return nodeClone;
    }
};