lintcode----线段树的构造II

概述:
线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)!
性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数组大小的四倍。

题目描述:
线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间。start和end都是整数,并按照如下的方式赋值:

根节点的 start 和 end 由 build 方法所给出。
对于节点 A 的左儿子,有 start=A.left, end=(A.left + A.right) / 2。
对于节点 A 的右儿子,有 start=(A.left + A.right) / 2 + 1, end=A.right。
如果 start 等于 end, 那么该节点是叶子节点,不再有左右儿子。
对于给定数组设计一个build方法,构造出线段树。

说明:
wiki:
Segment Tree
Interval Tree

样例:
给出[3,2,1,4],线段树将被这样构造

             [0,  3] (max = 4)
              /            \
    [0,  1] (max = 3)     [2, 3]  (max = 4)
    /        \               /             \

[0, 0](max = 3) [1, 1](max = 2)[2, 2](max = 1) [3, 3] (max = 4)

思路讲解:这里的思路就是跟二叉树的建立一样,运用递归的方法递归去建立,这里我们需要注意的就是关于递归的出口,我们设置的递归出口就是只有一个元素的时候即(low==high)的时候。

代码详解:

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end, max;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end, int max) {
 *         this->start = start;
 *         this->end = end;
 *         this->max = max;
 *         this->left = this->right = NULL;
 *     }
 * }
 */


class Solution {
public:
    /*
     * @param A: a list of integer
     * @return: The root of Segment Tree
     */
    SegmentTreeNode * build(vector<int> &A) {
        // write your code here
        if(A.size()==0){
            return NULL;
        }
        SegmentTreeNode *root=new SegmentTreeNode(0,0,0);
        SegmentTreeNode *head=root;
        BuildTree(root,A,0,A.size()-1);
        return head;
    }
    void BuildTree(SegmentTreeNode *root,vector<int> A,int low,int high)
    {
        if(low<high){
            int mid=(high+low)/2;
            root->start=low;
            root->end=high;
            root->max=findmax(A,low,high);

            root->left=new SegmentTreeNode(0,0,0);
            BuildTree(root->left,A,low,mid);

            root->right=new SegmentTreeNode(0,0,0);
            BuildTree(root->right,A,mid+1,high);

        }else if(low==high){

            root->start=low;
            root->end=high;
            root->max=A[low];
        }


    }
    int findmax(vector<int>res,int low ,int high){
        int max=INT_MIN;
        for(int i=low;i<=high;i++){
            if(max<res[i]){
                max=res[i];
            }
        }
        return max;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值