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 ...
随机推荐
- 【题解】CF559C C. Gerald and Giant Chess(容斥+格路问题)
[题解]CF559C C. Gerald and Giant Chess(容斥+格路问题) 55336399 Practice: Winlere 559C - 22 GNU C++11 Accepte ...
- Swift语言概览
Swift语言概览 关于 这篇文章简要介绍了苹果于WWDC 2014公布的编程语言--Swift. 前言 在这里我觉得有必要提一下Brec Victor的Invent ...
- python调试利器:最直观简洁的错误日志
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2018-08-30 17:12:27 # @Author : Sheldon (thi ...
- Java for LeetCode 112 Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- 基于node开发的web应用,负载均衡的简单实践
集群(cluster)是一组相互独立的.通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理.一个客户与集群相互作用时,集群像是一个独立的服务器. 负载均衡(Load Balance ...
- 服务器中判断客户端socket断开连接的方法【转】
本文转载自:http://www.cnblogs.com/jacklikedogs/p/3976208.html 1, 如果服务端的Socket比客户端的Socket先关闭,会导致客户端出现TIME_ ...
- Codeforces Round #551 (Div. 2) A~E题解
突然发现上一场没有写,那就补补吧 本来这场应该5题的,结果一念之差E fail了 A. Serval and Bus 基本数学不解释,假如你没有+1 -1真的不好意思见人了 #include<c ...
- awk添加文本到指定内容后一行
一下操作会输入到文件末尾,,测试不全面,还不如使用echo解决呢... 1. 要添加的文本内容如下: 文件名:code_list html</>!@$%^^ fdsafds <> ...
- HTML5响应式导航
HTML5响应式导航HTML5,响应式,jQuery特效,HTML5导航,HTML5响应式导航是一款基于HTML5实现的深灰色响应式导航菜单. 地址:http://www.huiyi8.com/sc/ ...
- 详解linux上定时函数 setitimer
setitimer()为Linux的API,并非C语言的Standard Library,setitimer()有两个功能, 一是指定一段时间后,才执行某个function,二是每间格一段时间就执行某 ...