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 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:
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的更多相关文章
- 【leetcode】699. Falling Squares
题目如下: On an infinite number line (x-axis), we drop given squares in the order they are given. The i- ...
- leetcode 699. Falling Squares 线段树的实现
线段树实现.很多细节值得品味 都在注释里面了 class SegTree: def __init__(self,N,query_fn,update_fn): self.tree=[0]*(2*N+2) ...
- Falling Squares
2020-01-08 10:16:37 一.Falling squares 问题描述: 问题求解: 本题其实也是一条经典的区间问题,对于区间问题,往往可以使用map来进行区间的维护操作. class ...
- [LeetCode] Falling Squares 下落的方块
On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...
- [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 ...
- LeetCode699. Falling Squares
On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
- leetcode 学习心得 (4)
645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...
- All LeetCode Questions List 题目汇总
All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...
随机推荐
- 支付宝异步通知notify_url接收不了问题解决(转)
此处return_url可以成功跳转回网站页面但notify_url却接收不到支付宝的异步通知.已保证notify_url是一个外网可以访问的网址 1.网站用的是ssh框架,当支付宝发通知到我这个ac ...
- [容易]在O(1)时间复杂度删除链表节点
题目来源:http://www.lintcode.com/zh-cn/problem/delete-node-in-the-middle-of-singly-linked-list/
- 网络新闻传输协议NNTP
一.Usenet与新闻组 Usenet新闻系统是一个全球存档的“电子公告板”,各种主题的新闻组一应俱全.新闻组可以是面向全球泛泛而谈,也可以是只面向某一个地区区域. 整个系统是由一个大量计算机组成的一 ...
- Java里的阻塞队列
JDK7提供了7个阻塞队列,如下: ArrayBlockingQueue : 一个数组结构组成的有界阻塞队列. LinkedBlockingQueue : 一个由链表结构组成的有界阻塞队列 . Pr ...
- excel根据数据源变化的动态图表
http://www.excelhome.net/lesson/article/excel/1798.html 这个链接讲的可以.
- RQNOJ 188 购物问题:树形dp
题目链接:https://www.rqnoj.cn/problem/188 题意: 商场以超低价格出售n个商品,购买第i个商品所节省的金额为w[i]. 为了防止亏本,有m对商品是不能同时买的.但保证商 ...
- 使用gdb调试c/c++代码
转自 http://blog.csdn.net/haoel/article/details/2879 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较 ...
- IDEA 设置代码行宽度
1.在File->settings->Editor->Code Style 2.在File->settings->Editor->Code Style->XM ...
- hdu-4417 Super Mario(树状数组 + 划分树)
题目链接: Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- C++中两个类相互包含引用问题
在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { in ...