本篇博客是关于七月算法 ,曹鹏老师所讲的关于图论部分的习题,加上自己的补充与笔记!
//给定二叉树的前序和中序遍历,构造二叉树 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;
}
};