leetcode 699. Falling Squares

来源:互联网 发布:青牛软件怎么样 编辑:程序博客网 时间:2024/06/06 06:36

699. Falling Squares

On an infinite number line (x-axis), we drop given squares in the order they are given.

The i-th square dropped (positions[i] = (left, side_length)) is a square with the left-most point being positions[i][0]and sidelength positions[i][1].

The square is dropped with the bottom edge parallel to the number line, and from a higher height than all currently landed squares. We wait for each square to stick before dropping the next.

The squares are infinitely sticky on their bottom edge, and will remain fixed to any positive length surface they touch (either the number line or another square). Squares dropped adjacent to each other will not stick together prematurely.


Return a list ans of heights. Each height ans[i] represents the current highest height of any square we have dropped, after dropping squares represented by positions[0], positions[1], ..., positions[i].

Example 1:

Input: [[1, 2], [2, 3], [6, 1]]Output: [2, 5, 5]Explanation:

After the first drop of positions[0] = [1, 2]:_aa_aa-------The maximum height of any square is 2.

After the second drop of positions[1] = [2, 3]:__aaa__aaa__aaa_aa___aa__--------------The maximum height of any square is 5. The larger square stays on top of the smaller square despite where its centerof gravity is, because squares are infinitely sticky on their bottom edge.

After the third drop of positions[1] = [6, 1]:__aaa__aaa__aaa_aa_aa___a--------------The maximum height of any square is still 5.Thus, we return an answer of [2, 5, 5].


Example 2:

Input: [[100, 100], [200, 100]]Output: [100, 100]Explanation: Adjacent squares don't get stuck prematurely - only their bottom edge can stick to surfaces.

Note:

  • 1 <= positions.length <= 1000.
  • 1 <= positions[i][0] <= 10^8.
  • 1 <= positions[i][1] <= 10^6.

    看了topic选择用线段树来做。

    结果貌似是测试数据有问题还是怎么回事。有个答案过不了,单独测试则是对的。




    下面是代码。

    class Solution {public:    vector<int> fallingSquares(vector<pair<int, int>>& positions)     {        vector<int> ret;        if (positions.empty()) return ret;        //首先需要知道这个整个的宽度。        int posmin = INT_MAX;        int posmax = INT_MIN;        for (auto it : positions)        {            posmin = min(posmin, it.first);            posmax = max(posmax, it.first + it.second - 1);        }        cout<< posmax <<" "<< posmin<<endl;        for (int i = 0; i < (posmax - posmin + 1) * 2; i++)            TreeMax.push_back(0);                 //Build(1, posmin, posmax); 其实不需要Build,因为最开始TreeMax都是 0, 是没有数据的。        for (auto it : positions)        {            //更新的是 新进入的区间的高度            int now_height = Quary_Total(1, posmin, posmax, it.first, it.first + it.second - 1) + it.second;            Update(1, posmin, posmax, it.first,it.first + it.second - 1, now_height);            //ret返回的是全场的高度            ret.push_back(TreeMax[1]);                        for (int i = 1; i <= (posmax - posmin + 1) * 2; i++)                cout<<TreeMax[i]<<" ";            cout<<endl;        }        return ret;    }        /*i 为当前编号, L, R为当前i节点的区间。 l、r 是使用者查询的区间*/        int Quary_Total(int i, int L, int R, int l, int r)     {        if (l == L && r == R) return TreeMax[i]; /*如果刚好是在当前区间*/        int Mid = (L + R) / 2;        if(l <= Mid && r > Mid)  //查询区间 在当前区间 的 左右两小部分 都有的情况            return max(Quary_Total(i * 2, L, Mid, l, Mid), Quary_Total(i * 2 + 1, Mid + 1, R, Mid + 1, r));        else if (r <= Mid) //只在左边部分             return Quary_Total(i * 2, L, Mid, l, r); /*递归左子树*/        else if (l > Mid)  //只在右边部分             return Quary_Total(i * 2 + 1, Mid + 1, R, l, r); /*递归右子树*/    }        /*i为当前编号,L,R为左右区间. l、r为修改范围的左右区间,B为修改的值*/    void Update(int i, int L, int R, int l, int r, int B)     {        if (L == R)  //已经缩小到单个了        {            /*如果找到了,修改值*/            TreeMax[i] = B;            return;        }        int Mid = (L + R) / 2;        if  (l <= Mid && r > Mid)         {            Update(i * 2, L, Mid, l, Mid, B); /*递归左子树*/            Update(i * 2 + 1, Mid + 1, R, Mid + 1, r, B); /*递归右子树*/        }        else if (r <= Mid)            Update(i * 2, L, Mid, l, r, B); /*递归左子树*/        else if (l > Mid)            Update(i * 2 + 1, Mid + 1, R, l, r, B); /*递归右子树*/                PushUp(i); //下面的子节点,需要把 修改后的和 传上来     }        /*区间 最值 处理*/    void PushUp(int Now)     {        TreeMax[Now] = max(TreeMax[Now * 2], TreeMax[Now * 2 + 1]);    }private:    vector<int> TreeMax; //注意 TreeMax编号是从1开始的};




  • 原创粉丝点击