The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants. A binary search tree (BST) is recursively defined as a binary tree which has the following properties:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
- Both the left and right subtrees must also be binary search trees.
6 8 6 3 1 2 5 4 8 7 2 5 8 7 1 9 12 -3 0 8 99 99Sample Output:
LCA of 2 and 5 is 3. 8 is an ancestor of 7. ERROR: 9 is not found. ERROR: 12 and -3 are not found. ERROR: 0 is not found. ERROR: 99 and 99 are not found.题目大意:给定给一个排序二叉树,即根结点的左子树中的元素的权值都比它的小,右子树都比它大。给出m个查询,每个查询有两个结点编号a和b,要求在给定的排序二叉树中找出a和b的最近的公共祖先结点。对于查询的结点,在给定的二叉树中不一定存在,用map对存在的结点进行标记即可。对于寻找LCA,如果a和b都比根结点小,那么共同祖先一定在左子树中,相反,一定在右子树中。由此我们可以写出递归函数。如果你采用遍历给定的先序遍历的序列,由此插入二叉树进行建树,会有2个测试点超时。对于LCA的查找函数,时间复杂度为O(logN),那么问题一定处在建树上,对于建树时间插入一个结点的最坏情况为O(N),那么插入N个就是就是N*N,我们可以通过对先序遍历序列排序后得到中序遍历,这样我们就可以通过先序遍历和中序遍历来建立二叉搜索树,将时间复杂度降为O(NlogN)代码中给出两种建树的方式。
#include <cstdio> #include <vector> #include <map> #include <algorithm> using namespace std; struct TreeNode { TreeNode *left, *right; int val; }; // TreeNode *build (TreeNode *root, int val) { // if (root == NULL) { // root = new TreeNode(); // root->left = root->right = NULL; // root->val = val; // } else if (val < root->val){ // root->left = build(root->left, val); // } else { // root->right = build(root->right, val); // } // return root; // } int dfs(TreeNode *root, int a, int b) { if (a < root->val && b < root->val) return dfs(root->left, a, b); if (a > root->val && b > root->val) return dfs(root->right, a, b); return root->val; } vector<int> pre, in; TreeNode *build(TreeNode *root, int a, int b, int x, int y, int n) { if (a > b || x > y) return root; int i = a; while (in[i] != pre[x]) i++; if (root == NULL) { root = new TreeNode(); root->left = root->right = NULL; } root->val = pre[x]; root->left = build(root->left, a, i-1, x+1, x+1+i-1-a, n); root->right = build(root->right,i+1, b, x+1+i-1-a+1, y, n); return root; } int m, n, val, a, b; map<int, int> book; int main () { scanf("%d%d", &m, &n); TreeNode *root = NULL; for (int i = 0; i < n; i++) { scanf("%d", &val); book[val] = 1; pre.push_back(val); in.push_back(val); // root = build(root, val); } sort(in.begin(), in.end()); root = build(root, 0, n-1, 0, n-1, n); // printf("%d\n", root->val); for (int i = 0; i < m; i++) { scanf("%d%d", &a, &b); if (book[a] == 0 && book[b] == 0) { printf("ERROR: %d and %d are not found.\n", a, b); continue; } if (book[a] == 0) { printf("ERROR: %d is not found.\n", a); continue; } if (book[b] == 0) { printf("ERROR: %d is not found.\n", b); continue; } int LCA = dfs(root, a, b); if (a != LCA && b != LCA) { printf("LCA of %d and %d is %d.\n", a, b, LCA); continue; } printf("%d is an ancestor of %d.\n", LCA, a == LCA ? b : a); } return 0; }
查看原文: http://iluhao.top/archives/627