LeetCode 1651: Hopper Company Queries III

Database

Problem Description

Explanation

In this problem, we are given an array of integers representing the heights of buildings. We need to answer a series of queries where each query asks for the maximum height of a building within a range [left, right].

To efficiently answer these queries, we can use the concept of a Segment Tree. We will build a Segment Tree where each node represents a range of heights in the original array. The root node will represent the range [0, n-1] where n is the number of buildings. Each internal node will represent the range of its two children. The leaf nodes will represent a single height in the original array.

For each query [left, right], we will traverse the Segment Tree to find the maximum height within that range. We will recursively check if the current node's range overlaps with the query range. If it doesn't, we return a default value (e.g., Integer.MIN_VALUE). If it does, we check if the current node's range is fully within the query range. If it is, we return the maximum height stored in that node. If not, we recursively check both children nodes.

Time Complexity: O(n log n) for building the Segment Tree and O(log n) for each query. Space Complexity: O(n) for the Segment Tree.

Solutions

class SegmentTree {
    int[] tree;
    int n;

    public SegmentTree(int[] heights) {
        n = heights.length;
        tree = new int[4*n];
        build(heights, 0, 0, n-1);
    }

    private void build(int[] heights, int idx, int left, int right) {
        if (left == right) {
            tree[idx] = heights[left];
            return;
        }
        int mid = left + (right - left) / 2;
        build(heights, 2*idx+1, left, mid);
        build(heights, 2*idx+2, mid+1, right);
        tree[idx] = Math.max(tree[2*idx+1], tree[2*idx+2]);
    }

    public int query(int left, int right) {
        return queryHelper(0, 0, n-1, left, right);
    }

    private int queryHelper(int idx, int segLeft, int segRight, int left, int right) {
        if (left > segRight || right < segLeft) {
            return Integer.MIN_VALUE;
        }
        if (left <= segLeft && right >= segRight) {
            return tree[idx];
        }
        int mid = segLeft + (segRight - segLeft) / 2;
        return Math.max(queryHelper(2*idx+1, segLeft, mid, left, right),
                        queryHelper(2*idx+2, mid+1, segRight, left, right));
    }
}

Loading editor...