数据结构 - Codeforces Round #353 (Div. 2) D. Tree Construction

本文介绍了一种高效算法,用于根据给定数值序列构造二叉搜索树,并输出每个非根节点的父节点值。通过使用Java的TreeMap容器,避免了完全构建树的过程,在O(n*logn)的时间复杂度内解决问题。
Tree Construction 

Problem's Link

 ----------------------------------------------------------------------------

Mean: 

给定n个数,按照构造Binary Search Tree的方式来构造BST树,按顺序输出每一个非root结点的父节点的值。

analyse:

构造BST树最坏情况下时间复杂度为O(n),肯定会超时。

注意到只需要输出结点的父节点的值,不需要真的构造BST树。

插到第i个结点时,我们在前i-1个结点中找两个数,一个是比Ai大的最小数,一个是比Ai小的最大数。

那么Ai的父节点肯定是这两个中的一个,到底是哪一个呢,根据画图分析,可以得出是后来插入的那个。

如下图所示:

做法:用java里面的容器TreeMap<Integer,Integer>来存储<value,index>对,根据value值来查找,然后比较这两个数的index大小来判断谁是父节点。

 

Time complexity: O(n*logn)

 

view code

1.使用java容器实现
import java.io.BufferedInputStream;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {
    public static void main( String [] argv ){
        Scanner in = new Scanner( new BufferedInputStream( System . in));
        while( in . hasNext ()){
            int n = in . nextInt();
            TreeSet < Integer > vals = new TreeSet <>();
            HashMap < Integer , Integer > idx = new HashMap <>();
            int val = in . nextInt();
            vals . add( val);
            idx . put( val , 0);
            for( int i = 1; i <n ;++ i ){
                val = in . nextInt();
                Integer hi = vals . higher( val ), lo = vals . lower( val);
                if( hi == null)
                    System . out . print( lo + " ");
                else if( lo == null)
                    System . out . print( hi + " ");
                else {
                    Integer hiIdx = idx . get( hi);
                    Integer loIdx = idx . get( lo);
                    if( hiIdx > loIdx)
                        System . out . print( hi + " ");
                    else
                        System . out . print( lo + " ");
                }
                vals . add( val);
                idx . put( val , i);
            }
            System . out . println();
        }
    }
}
 
 
2.线段树实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值