您的位置:首页 > 其它

Cracking the Coding Interview: Trees and Graphs

2017-03-12 17:00 441 查看
Validate BST

Successor

Route Between Nodes

List of Depths

First Common Ancestor

Path With Sum

Validate BST

判断一个二叉树是不是二叉查找树。

/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/

class Checker {
public:
int lst = 0;
bool fst = true;
bool checkBST(TreeNode* root) {
// write code here
if(!root) return true;
bool ltree = checkBST(root->left);
if(fst) { lst = root->val; fst = false; }
else { if(lst > root->val) return false; lst = root->val; }
bool rtree = checkBST(root->right);
return ltree&&rtree;
}
};


Successor

这道题目寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。

给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。

代码实现:在这里我设置了一个类似于状态机的东西,isFind为0的时候,那么就是没有找到节点值为p的节点;为1的时候就是找到了;为2的时候就是找到之后的后继了;然后在找到后继之后比较是否重复。

class Successor {
public:
int res = -1;
int isFind = 0; // 1 is found; 2 is replicate
int findSucc(TreeNode* root, int p) {
// write code here
if(!root) return -1;
int lres = findSucc(root->left, p);
if(isFind == 1) { res = root->val; isFind = 2; }
if(root->val == p && !isFind) isFind = 1;
if(isFind == 2) { if(root->val == res) return -1; }
int rres = findSucc(root->right, p);

return res;
}
};


Route Between Nodes

对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径。

给定图中的两个结点的指针UndirectedGraphNode* a,UndirectedGraphNode* b(请不要在意数据类型,图是有向图),请返回一个bool,代表两点之间是否存在一条路径(a到b或b到a)。

这里需要注意的是需要判断是否有环的存在,因为环的存在使得队列是无穷大,所以需要有些机制判断是否存在环,以及路径可以从a到b,也可以从b到a,这点需要注意一下。别的东西没有什么提示了,就是一个简单的BFS。

/*
struct UndirectedGraphNode {
int label;
vector<struct UndirectedGraphNode *> neighbors;
UndirectedGraphNode(int x) : label(x) {}
};*/

class Path {
public:
bool checkPath(UndirectedGraphNode* a, UndirectedGraphNode* b) {
// write code here
queue<UndirectedGraphNode* > que;
que.push(a);
while(!que.empty()) {
UndirectedGraphNode* tp1 = que.front();
que.pop();
if(tp1->label == b->label) return true;
if(!tp1->label) tp1->label = INT_MIN;
else tp1->label = -1*tp1->label;
for(int i = 0, sz = tp1->neighbors.size(); i < sz; i++)
if(tp1->neighbors[i]->label >= 0)
que.push(tp1->neighbors[i]);
}

que.push(b);
while(!que.empty()) {
UndirectedGraphNode* tp2 = que.front();
que.pop();
if(tp2->label == INT_MIN) tp2->label = 0;
else if(tp2->label < 0) tp2->label = abs(tp2->label);
if(tp2->label == a->label) return true;
tp2->label = INT_MAX;
for(int i = 0, sz = tp2->neighbors.size(); i < sz; i++)
if(tp2->neighbors[i]->label != INT_MAX)
que.push(tp2->neighbors[i]);
}

return false;
}
};


List of Depths

这道题目就是给出一个数组,它需要把数组构成二叉树,然后就是计算构成最短二叉树的深度。

class MinimalBST {
public:
int buildMinimalBST(vector<int> vals) {
// write code here
int size = vals.size() + 1;
int D = ceil(log(size)/log(2));
return D;
}
};


First Common Ancestor

有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。

给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。

测试样例:

2,3

返回:1

class LCA {
public:
int getLCA(int a, int b) {
// write code here
while(a != b) {
if(a > b) a = a >> 1;
else b = b >> 1;
}
return a;
}
};


Path With Sum

这道题目是使用了DFS来计算,输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

但是这只是其中一个比较简单的版本,想想如果是不规定起始节点和结束节点呢。

/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void findPath(vector<vector<int> >& res, vector<int> tmp, int tar, int cur, TreeNode* root) {
if(!root) {
if(cur == tar) res.push_back(tmp);
return;
}
cur += root->val;
tmp.push_back(root->val);
if(root->left || root->right) {
findPath(res, tmp, tar, cur, root->left);
findPath(res, tmp, tar, cur, root->right);
}
else findPath(res, tmp, tar, cur, root->left);
}

vector<vector<int> > FindPath(TreeNode* root,int tar) {
vector<int> tmp;
vector<vector<int> > res;
if(!root) return res;
int cur = 0;
findPath(res, tmp, tar, cur, root);
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息