class Solution {
public:
vector<bool> getResults(vector<vector<int>>& queries) {
}
};
100314. 物块放置查询
有一条无限长的数轴,原点在 0 处,沿着 x 轴 正 方向无限延伸。
给你一个二维数组 queries
,它包含两种操作:
queries[i] = [1, x]
。在距离原点 x
处建一个障碍物。数据保证当操作执行的时候,位置 x
处 没有 任何障碍物。queries[i] = [2, x, sz]
。判断在数轴范围 [0, x]
内是否可以放置一个长度为 sz
的物块,这个物块需要 完全 放置在范围 [0, x]
内。如果物块与任何障碍物有重合,那么这个物块 不能 被放置,但物块可以与障碍物刚好接触。注意,你只是进行查询,并 不是 真的放置这个物块。每个查询都是相互独立的。请你返回一个 boolean 数组results
,如果第 i
个操作类型 2 的操作你可以放置物块,那么 results[i]
为 true
,否则为 false
。
示例 1:
输入:queries = [[1,2],[2,3,3],[2,3,1],[2,2,2]]
输出:[false,true,true]
解释:
查询 0 ,在 x = 2
处放置一个障碍物。在 x = 3
之前任何大小不超过 2 的物块都可以被放置。
示例 2:
输入:queries = [[1,7],[2,7,6],[1,2],[2,7,5],[2,7,6]]
输出:[true,true,false]
解释:
x = 7
处放置一个障碍物。在 x = 7
之前任何大小不超过 7 的物块都可以被放置。x = 2
处放置一个障碍物。现在,在 x = 7
之前任何大小不超过 5 的物块可以被放置,x = 2
之前任何大小不超过 2 的物块可以被放置。
提示:
1 <= queries.length <= 15 * 104
2 <= queries[i].length <= 3
1 <= queries[i][0] <= 2
1 <= x, sz <= min(5 * 104, 3 * queries.length)
x
处不会有障碍物。原站题解
golang 解法, 执行用时: 670 ms, 内存消耗: 30.2 MB, 提交时间: 2024-05-26 19:11:40
type seg []int // 把 i 处的值改成 val func (t seg) update(o, l, r, i, val int) { if l == r { t[o] = val return } m := (l + r) >> 1 if i <= m { t.update(o<<1, l, m, i, val) } else { t.update(o<<1|1, m+1, r, i, val) } t[o] = max(t[o<<1], t[o<<1|1]) } // 查询 [0,R] 中的最大值 func (t seg) query(o, l, r, R int) int { if r <= R { return t[o] } m := (l + r) >> 1 if R <= m { return t.query(o<<1, l, m, R) } return max(t[o<<1], t.query(o<<1|1, m+1, r, R)) } func getResults(queries [][]int) (ans []bool) { m := 0 for _, q := range queries { m = max(m, q[1]) } m++ set := redblacktree.New[int, struct{}]() set.Put(0, struct{}{}) // 哨兵 set.Put(m, struct{}{}) t := make(seg, 2<<bits.Len(uint(m))) for _, q := range queries { x := q[1] if q[0] == 1 { pre, _ := set.Floor(x) // x 左侧最近障碍物的位置 nxt, _ := set.Ceiling(x) // x 右侧最近障碍物的位置 set.Put(x, struct{}{}) t.update(1, 0, m, x, x-pre.Key) // 更新 d[x] = x - pre t.update(1, 0, m, nxt.Key, nxt.Key-x) // 更新 d[nxt] = nxt - x } else { pre, _ := set.Floor(x - 1) // x 左侧最近障碍物的位置 // 最大长度要么是 [0,pre] 中的最大 d,要么是 [pre,x] 这一段的长度 maxGap := max(t.query(1, 0, m, pre.Key), x-pre.Key) ans = append(ans, maxGap >= q[2]) } } return }
java 解法, 执行用时: 378 ms, 内存消耗: 150.3 MB, 提交时间: 2024-05-26 19:11:27
class Solution { public List<Boolean> getResults(int[][] queries) { int m = 0; for (int[] q : queries) { m = Math.max(m, q[1]); } m++; TreeSet<Integer> set = new TreeSet<>(List.of(0, m)); // 哨兵 int[] t = new int[2 << (32 - Integer.numberOfLeadingZeros(m))]; List<Boolean> ans = new ArrayList<>(); for (int[] q : queries) { int x = q[1]; if (q[0] == 1) { int pre = set.floor(x); // x 左侧最近障碍物的位置 int nxt = set.ceiling(x); // x 右侧最近障碍物的位置 set.add(x); update(t, 1, 0, m, x, x - pre); // 更新 d[x] = x - pre update(t, 1, 0, m, nxt, nxt - x); // 更新 d[nxt] = nxt - x } else { int pre = set.floor(x - 1); // x 左侧最近障碍物的位置 // 最大长度要么是 [0,pre] 中的最大 d,要么是 [pre,x] 这一段的长度 int maxGap = Math.max(query(t, 1, 0, m, pre), x - pre); ans.add(maxGap >= q[2]); } } return ans; } // 把 i 处的值改成 val private void update(int[] t, int o, int l, int r, int i, int val) { if (l == r) { t[o] = val; return; } int m = (l + r) / 2; if (i <= m) { update(t, o * 2, l, m, i, val); } else { update(t, o * 2 + 1, m + 1, r, i, val); } t[o] = Math.max(t[o * 2], t[o * 2 + 1]); } // 查询 [0,R] 中的最大值 private int query(int[] t, int o, int l, int r, int R) { if (r <= R) { return t[o]; } int m = (l + r) / 2; if (R <= m) { return query(t, o * 2, l, m, R); } return Math.max(t[o * 2], query(t, o * 2 + 1, m + 1, r, R)); } }
cpp 解法, 执行用时: 840 ms, 内存消耗: 269.5 MB, 提交时间: 2024-05-26 19:11:15
class Solution { vector<int> t; // 把 i 处的值改成 val void update(int o, int l, int r, int i, int val) { if (l == r) { t[o] = val; return; } int m = (l + r) / 2; if (i <= m) { update(o * 2, l, m, i, val); } else { update(o * 2 + 1, m + 1, r, i, val); } t[o] = max(t[o * 2], t[o * 2 + 1]); } // 查询 [0,R] 中的最大值 int query(int o, int l, int r, int R) { if (r <= R) { return t[o]; } int m = (l + r) / 2; if (R <= m) { return query(o * 2, l, m, R); } return max(t[o * 2], query(o * 2 + 1, m + 1, r, R)); } public: vector<bool> getResults(vector<vector<int>>& queries) { int m = 0; for (auto& q : queries) { m = max(m, q[1]); } m++; set<int> st{0, m}; // 哨兵 t.resize(2 << (32 - __builtin_clz(m))); vector<bool> ans; for (auto& q : queries) { int x = q[1]; auto it = st.lower_bound(x); int pre = *prev(it); // x 左侧最近障碍物的位置 if (q[0] == 1) { int nxt = *it; // x 右侧最近障碍物的位置 st.insert(x); update(1, 0, m, x, x - pre); // 更新 d[x] = x - pre update(1, 0, m, nxt, nxt - x); // 更新 d[nxt] = nxt - x } else { // 最大长度要么是 [0,pre] 中的最大 d,要么是 [pre,x] 这一段的长度 int max_gap = max(query(1, 0, m, pre), x - pre); ans.push_back(max_gap >= q[2]); } } return ans; } };
python3 解法, 执行用时: 4319 ms, 内存消耗: 77.3 MB, 提交时间: 2024-05-26 19:10:59
from sortedcontainers import SortedList class Solution: def getResults(self, queries: List[List[int]]) -> List[bool]: m = max(q[1] for q in queries) + 1 t = [0] * (2 << m.bit_length()) # 把 i 处的值改成 val def update(o: int, l: int, r: int, i: int, val: int) -> None: if l == r: t[o] = val return m = (l + r) // 2 if i <= m: update(o * 2, l, m, i, val) else: update(o * 2 + 1, m + 1, r, i, val) t[o] = max(t[o * 2], t[o * 2 + 1]) # 查询 [0,R] 中的最大值 def query(o: int, l: int, r: int, R: int) -> int: if r <= R: return t[o] m = (l + r) // 2 if R <= m: return query(o * 2, l, m, R) return max(t[o * 2], query(o * 2 + 1, m + 1, r, R)) sl = SortedList([0, m]) # 哨兵 ans = [] for q in queries: x = q[1] i = sl.bisect_left(x) pre = sl[i - 1] # x 左侧最近障碍物的位置 if q[0] == 1: nxt = sl[i] # x 右侧最近障碍物的位置 sl.add(x) update(1, 0, m, x, x - pre) # 更新 d[x] = x - pre update(1, 0, m, nxt, nxt - x) # 更新 d[nxt] = nxt - x else: # 最大长度要么是 [0,pre] 中的最大 d,要么是 [pre,x] 这一段的长度 max_gap = max(query(1, 0, m, pre), x - pre) ans.append(max_gap >= q[2]) return ans