1143. Lowest Common Ancestor (30) 思維 + O(n)建立BST樹

傳送門


思路:

    果然是個很水的題,當時把自己考崩了,預感到涼了結果就真的涼了...當時也是zz,爲啥老想着建樹呢》????首先要判斷是否出現過,肯定是map一下了.


其次就是找LCA,(考場傻逼到手剛LCA),因爲這是一個BST樹所以存在一個很重要的性質就是 左<根<右.

    那麼對於給定的兩個值我們從根節點開始,往下走,總會走到一個節點分叉,那麼這個點就是他們的最近公共祖先了.

那麼最多1w個點,我們每次直接for一下就好了啊,找到 一個節點值 >  u1 ,< u2的即可.

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e4+5;
int n,m;
map<int,int>mp;
int a[maxn];
int main()
{
	while(~scanf("%d %d",&m,&n))
	{
		mp.clear();
		for(int i = 1;i <= n;++i)
		{
			scanf("%d",&a[i]);
			mp[a[i]] = 1;
		}
		for(int i = 1;i <= m;++i)
		{
			int u,v;
			scanf("%d %d",&u,&v);
			if(mp[u] == 0 && mp[v] == 0)
			printf("ERROR: %d and %d are not found.\n",u,v);
			else if(mp[u] == 0 || mp[v] == 0)
			printf("ERROR: %d is not found.\n",mp[u] == 0?u : v); 
			else
			{
				int f ;
				for(int j = 1;j <= n;++j)
				{
					f = a[j];
					if((f > v && f < u) || (f > u && f < v) || f == u || f == v) 
						break;
				} 
				if(f == u || f == v)
				printf("%d is an ancestor of %d.\n",f,u == f ? v : u);
				else
				printf("LCA of %d and %d is %d.\n",u,v,f);
			}
		}
	}
	return 0;
}


當然這個題建樹也是可以做,先建樹在跑LCA.由於1w個點,所以每次輸入一個Insert,當是一條鏈就T了(-.-我就是這樣T到死的)

這裏來學一個新的建樹方法,遞歸O(n)建立BST樹.考慮到給定的爲一個先序遍歷,那麼肯定是“根左右”,也就是第一個一定是根節點,那麼怎麼找到哪些是左子樹哪些是右子樹中的節點呢?還是利用BST的性質,左面都比根節點小右面都比根節點大,所以我們只需把當前區間的序列和根節點比較,直到找到一個大於他的就是左右子樹間的分界線了,然後一直遞歸下去.

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e4+5;
int a[maxn];
int n,m;
map<int,int>mp;
struct node
{
    int val;
    node *l;
    node *r;
    node()
    {
        l = r = nullptr;
    }
};
node* build(int l,int r)
{
    if(l > r) return nullptr;
    if(l == r)
    {
        node *tmp = new node;
        tmp -> val = a[l];
        //cout << '-' << ' ' << tmp -> val << endl;
        return tmp;
    }
    int i = l + 1;
    while(i <= r && a[i] < a[l]) ++i;
    node *tmp = new node;
    tmp -> val = a[l];
   //cout << '*' << ' ' << tmp -> val << endl;
    tmp -> l = build(l + 1,i - 1);
    tmp -> r = build(i,r);
    return tmp;
}
int _find(node *root,int u,int v)
{
    if(root == nullptr) return -1;
    //cout << root -> val << endl;
    if(root -> val == u || root -> val == v)
        return root -> val;
    if(root -> val > u && root -> val < v)
        return root -> val;
    if(root ->  val > v)
    return _find(root -> l,u,v);
    if(root -> val < u)
    return _find(root -> r,u,v);
}
int main()
{
    while(~scanf("%d %d",&m,&n))
    {
        mp.clear();
        for(int i = 1;i <= n;++i)
        {
           scanf("%d",&a[i]);
           mp[a[i]] = 1;
        }
        node *root;
        root = build(1,n);
      //  cout << root -> val<<endl;
        for(int i = 1;i <= m;++i)
        {
            int u,v;
            scanf("%d %d",&u,&v);
            if(mp[u] == 0 && mp[v] == 0)
                printf("ERROR: %d and %d are not found.\n",u,v);
            else if(mp[u] == 0 || mp[v] == 0)
                printf("ERROR: %d is not found.\n",mp[u] == 0 ? u : v);
            else
            {
                int x1 = u,x2 = v;
                if(x1 > x2) swap(x1,x2);
               int f = _find(root,x1,x2);
               if(f == u || f == v)
                    printf("%d is an ancestor of %d.\n",f,f == u ? v : u);
                else
                    printf("LCA of %d and %d is %d.\n",u,v,f);
            }

        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章