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 center of 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.

Approach #1: C++. [Brute Force]

class Solution {
public:
vector<int> fallingSquares(vector<pair<int, int>>& positions) {
vector<int> ans;
vector<Interval> intervals;
int maxHeight = INT_MIN;
for (const auto& it : positions) {
int start = it.first;
int end = start + it.second;
int baseHeight = 0;
for (const auto& it : intervals) {
if (start >= it.end || end <= it.start) {
continue;
}
baseHeight = max(baseHeight, it.height);
}
int height = it.second + baseHeight;
maxHeight = max(maxHeight, height);
intervals.push_back(Interval(start, end, height));
ans.push_back(maxHeight);
}
return ans;
} private:
struct Interval {
int start;
int end;
int height;
Interval(int start, int end, int height)
: start(start), end(end), height(height) {}
};
};

  

Approach #2: C++. [Using Map]

class Solution {
public:
vector<int> fallingSquares(vector<pair<int, int>>& positions) {
vector<int> ans;
map<pair<int, int>, int> b;
int maxHeight = INT_MIN;
for (const auto& kv : positions) {
int start = kv.first;
int size = kv.second;
int end = start + size; auto it = b.upper_bound({start, end}); if (it != b.begin()) {
auto it2 = it;
if ((--it2)->first.second > start)
it = it2;
} int baseHeight = 0;
vector<tuple<int, int, int>> ranges; while (it != b.end() && it->first.first < end) {
const int s = it->first.first;
const int e = it->first.second;
const int h = it->second; if (s < start) ranges.emplace_back(s, start, h);
if (e > end) ranges.emplace_back(end, e, h); baseHeight = max(baseHeight, h);
it = b.erase(it);
} int newHeight = size + baseHeight; b[{start, end}] = newHeight; for (const auto& range : ranges) {
b[{get<0>(range), get<1>(range)}] = get<2>(range);
} maxHeight = max(maxHeight, newHeight);
ans.push_back(maxHeight);
}
return ans;
}
};

  

Notes:

1. tuples in c++.

Approach #3: Java. [segment tree]

class Solution {
public List<Integer> fallingSquares(int[][] positions) {
int n = positions.length;
Map<Integer, Integer> cc = coorCompression(positions);
int best = 0;
List<Integer> res = new ArrayList<>();
SegmentTree tree = new SegmentTree(cc.size());
for (int[] pos : positions) {
int L = cc.get(pos[0]);
int R = cc.get(pos[0] + pos[1] - 1);
int h = tree.query(L, R) + pos[1];
tree.update(L, R, h);
best = Math.max(best, h);
res.add(best);
}
return res;
} private Map<Integer, Integer> coorCompression(int[][] positions) {
Set<Integer> set = new HashSet<>();
for (int[] pos : positions) {
set.add(pos[0]);
set.add(pos[0] + pos[1] - 1);
}
List<Integer> list = new ArrayList<>(set);
Collections.sort(list);
Map<Integer, Integer> map = new HashMap<>();
int t = 0;
for (int pos : list) map.put(pos, t++);
return map;
} class SegmentTree {
int[] tree;
int N; SegmentTree(int N) {
this.N = N;
int n = (1 << ((int) Math.ceil(Math.log(N) / Math.log(2)) + 1));
tree = new int[n];
} public int query(int L, int R) {
return queryUtil(1, 0, N - 1, L, R);
} private int queryUtil(int index, int s, int e, int L, int R) {
// out of range
if (s > e || s > R || e < L) {
return 0;
}
// [L, R] cover [s, e]
if (s >= L && e <= R) {
return tree[index];
}
// Overlapped
int mid = s + (e - s) / 2;
return Math.max(queryUtil(2 * index, s, mid, L, R), queryUtil(2 * index + 1, mid + 1, e, L, R));
} public void update(int L, int R, int h) {
updateUtil(1, 0, N - 1, L, R, h);
} private void updateUtil(int index, int s, int e, int L, int R, int h) {
// out of range
if (s > e || s > R || e < L) {
return;
}
tree[index] = Math.max(tree[index], h);
if (s != e) {
int mid = s + (e - s) / 2;
updateUtil(2 * index, s, mid, L, R, h);
updateUtil(2 * index + 1, mid + 1, e, L, R, h);
}
}
}
}

  

699. Falling Squares的更多相关文章

  1. 【leetcode】699. Falling Squares

    题目如下: On an infinite number line (x-axis), we drop given squares in the order they are given. The i- ...

  2. leetcode 699. Falling Squares 线段树的实现

    线段树实现.很多细节值得品味 都在注释里面了 class SegTree: def __init__(self,N,query_fn,update_fn): self.tree=[0]*(2*N+2) ...

  3. Falling Squares

    2020-01-08 10:16:37 一.Falling squares 问题描述: 问题求解: 本题其实也是一条经典的区间问题,对于区间问题,往往可以使用map来进行区间的维护操作. class ...

  4. [LeetCode] Falling Squares 下落的方块

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

  5. [Swift]LeetCode699. 掉落的方块 | Falling Squares

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

  6. LeetCode699. Falling Squares

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

  7. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  8. leetcode 学习心得 (4)

    645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...

  9. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

随机推荐

  1. Linux就该这么学--命令集合11(配置系统相关信息)

    1.配置主机名称: 查看主机名: hostname 修改主机名: vim /etc/hostname 2.配置网卡信息: 在红帽RHEL6系统中网卡配置文件的前缀为“ifcfg-eth”,第一块即为“ ...

  2. 【AWS】亚马逊云常用服务解释

    新公司使用的是亚马逊服务,刚开始的时候,对很多名词不太明白,总结了一下如下 1,EC2 这个是亚马逊的一种服务器服务,可以理解为跟vmware差不多,EC2为虚拟机提供载体,EC2上跑虚拟机服务器. ...

  3. 跳转appStore评分

    跳转到AppStore让用户能够给我们的应用进行评分,有两种方法,一种是跳出应用,跳转到AppStore,进行评分.另一种是在应用内,内置AppStore进行评分. PS:appleID在https: ...

  4. css(3)

    行内元素和块内元素可以通过定义display的属性值进行相互转换. 想要叫ul中的li实现横向显示可以在li中加入布局"float:left": 如: /*这个用于控制单个图片区域 ...

  5. kvm初体验之一:参考文档

    KVM Virtualization in RHEL 6 Made Easy KVM Virtualization in RHEL 6 Made Easy – Part 2 RHEL 6 Virtua ...

  6. Speaking 1

    What clothes do you usually like to wear?Well I like fashionable clothes, but I also want to be comf ...

  7. elasticsearch-installation

    1. 安装Java JDK 移步 :sdfa 2. 下载elasticsearch url : https://artifacts.elastic.co/downloads/elasticsearch ...

  8. 浅析linux 下shell命令执行和守护进程

    执行shell脚本有以下几种方式 1.相对路径方式,需先cd到脚本路径下 [root@banking tmp]# cd /tmp [root@banking tmp]# ./ceshi.sh 脚本执行 ...

  9. NO0:重新拾起C语言

    因工作所需,重新捡起C语言,之前在学校里有接触过,但现在已经忘的一干二净了,现决定重新开始学习,为工作,为生活. 以<标准 C程序设计 第5版>的课程进行基础学习,同时以另外两本书为辅助, ...

  10. BZOJ_2813_奇妙的Fibonacci_线性筛

    BZOJ_2813_奇妙的Fibonacci_线性筛 Description Fibonacci数列是这样一个数列: F1 = 1, F2 = 1, F3 = 2 . . . Fi = Fi-1 + ...