zoukankan      html  css  js  c++  java
  • Lintcode---线段树查询(区间最大值)

    对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max,值为该节点所代表的数组区间start到end内的最大值。

    为SegmentTree设计一个 query 的方法,接受3个参数root, startend,线段树root所代表的数组中子区间[start, end]内的最大值。

     注意事项

    在做此题之前,请先完成 线段树构造 这道题目。

    样例

    对于数组 [1, 4, 2, 3], 对应的线段树为:

                      [0, 3, max=4]
                     /             
              [0,1,max=4]        [2,3,max=3]
              /                 /         
       [0,0,max=1] [1,1,max=4] [2,2,max=2], [3,3,max=3]
    

    query(root, 1, 1), return 4

    query(root, 1, 2), return 4

    query(root, 2, 3), return 3

    query(root, 0, 2), return 4

    思路:当遇到一些关于对连续点的修改和统计的问题时,可以考虑用线段树来解决。
         这属于典型的RMQ问题(区间最值查询问题),所以最好通过构建线段树,利用线段树的性质来求解,这样将问题转化成线段树,会让复杂度降低到log(n);
              
         还是要用递归的思路解决。先写出基准情形,然后递归解决。思路和上一篇博客求解给定区间元素个数一模一样。

         都是借助于线段树本身的性质,减小算法的时间复杂度。

    /**
     * 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 root, start, end: The root of segment tree and 
         *                         an segment / interval
         *@return: The maximum number in the interval [start, end]
         */
         
        /*
        思路:当遇到一些关于对连续点的修改和统计的问题时,可以考虑用线段树来解决。
              这属于典型的RMQ问题(区间最值查询问题),所以最好通过构建线段树,利用线段树的性质来求解!!
              这样将问题转化成线段树,会让复杂度降低到log(n);
              
              还是要用递归的思路解决。先写出基准情形,然后递归解决。
        */
        int query(SegmentTreeNode *root, int start, int end) {
            // write your code here
            
            if(!root||start>end){
                return 0;
            }
            
            if(root->start>=start&&root->end<=end){
                return root->max;
            }
            
            int mid=root->start+(root->end-root->start)/2;
            
            if(start>mid){
                return query(root->right,start,end);
            }
            else if(end<mid){
                return query(root->left,start,end);
            }
            else return max(query(root->left,start,mid),query(root->right,mid+1,end));
        }
    };
    
  • 相关阅读:
    分布式缓存HttpRuntime.cache应用到单点登陆中_优化登陆
    ID Codes
    Smith Numbers经典
    青蛙的约会
    exp_euler两种形式int,void(扩展欧几里得算法)可求最大公约数,二元一次方程的解
    A/B
    Raising Modulo Numbers
    Brave balloonists 求素因子的个数
    排列
    Anagram
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/7085666.html
Copyright © 2011-2022 走看看