1143 Lowest Common Ancestor (两结点的最近公共祖先)
大致题意就是给出一个二叉查找树BST的先序遍历序列,然后再给出任意一对结点,如果结点不合法,那么输出不合法信息;否则,找出其最近祖先结点。
注意点:
1,如果已知二叉查找树BST的先序(后序)遍历序列,可以对序列进行按从小到大排序,得到中序遍历序列,进一步由先序、中序遍历序列可以唯一构造出一棵二叉树。
2,如果按照这题的方法1151 LCA in a Binary Tree(两结点的最近公共祖先),会导致超时。
思路分析:
首先在草稿纸上,构造出这棵二叉查找树。
假设给出的顶点是a,b,且合法。
会发现在先序序列中,从左往右第一次出现的结点 u,使得 u>= a&& u<=b,或者 u>= b&& u<=a,那么这个u 即为a,b的最近祖先结点。
1 #include<iostream> 2 #include<vector> 3 #include<map> 4 #include<algorithm> 5 using namespace std; 6 int main() { 7 int m,n,a,b,u; 8 cin>>m>>n; 9 vector<int> pre(n); 10 map<int,bool> mp; 11 for(int i = 0; i < n; ++i) { 12 cin>>pre[i]; 13 mp[pre[i]] = true; 14 } 15 for(int i = 0; i < m; ++i) { 16 cin>>a>>b; 17 for(int j = 0; j < n; ++j) { //顺序遍历先序序列 18 u = pre[j]; 19 if((u >= a && u <= b) ||(u >= b && u <= a)) break; 20 } 21 if(mp[a] == 0 && mp[b] == 0) printf("ERROR: %d and %d are not found.\n",a,b); 22 else if(mp[a] == 0 || mp[b] == 0) printf("ERROR: %d is not found.\n",mp[a] == 0?a:b); 23 else if(u == a || u == b) printf("%d is an ancestor of %d.\n",u,u == a?b:a); 24 else printf("LCA of %d and %d is %d.\n",a,b,u); 25 } 26 return 0; 27 }
ps:发现一个规律,如果压轴题限时在200ms以内,这时往往需要借助map,或者考察某个性质,或者找这题的规律,所以一定要在纸上慢慢推敲。