From e4878eb2183efb1f0a1b08bc06c0978bf855d9fa Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Sun, 29 Dec 2024 23:00:44 +0100 Subject: [PATCH] =?UTF-8?q?java:=20add=20=C2=AB2940.=20Find=20Building=20W?= =?UTF-8?q?here=20Alice=20and=20Bob=20Can=20Meet=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit URL: https://leetcode.com/problems/find-building-where-alice-and-bob-can-meet/ Signed-off-by: Matej Focko --- ...building-where-alice-and-bob-can-meet.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 java/find-building-where-alice-and-bob-can-meet.java diff --git a/java/find-building-where-alice-and-bob-can-meet.java b/java/find-building-where-alice-and-bob-can-meet.java new file mode 100644 index 0000000..f9b40fb --- /dev/null +++ b/java/find-building-where-alice-and-bob-can-meet.java @@ -0,0 +1,71 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class Solution { + private record Query(int height, int index) {} + + private static List> process(int[] heights, int[][] originalQueries, int[] result) { + List> queries = new ArrayList<>(heights.length); + for (var i = 0; i < heights.length; ++i) { + queries.add(new ArrayList<>()); + } + + for (var i = 0; i < originalQueries.length; ++i) { + int a = Math.min(originalQueries[i][0], originalQueries[i][1]); + int b = Math.max(originalQueries[i][0], originalQueries[i][1]); + + if (heights[b] > heights[a] || a == b) { + result[i] = b; + } else { + queries.get(b).add(new Query(heights[a], i)); + } + } + + return queries; + } + + private int search(List stack, int height) { + int l = 0; + int r = stack.size() - 1; + + var index = -1; + while (l <= r) { + var mid = (l + r) / 2; + if (stack.get(mid).height > height) { + index = Math.max(index, mid); + l = mid + 1; + } else { + r = mid - 1; + } + } + + return index; + } + + public int[] leftmostBuildingQueries(int[] heights, int[][] originalQueries) { + var result = new int[originalQueries.length]; + Arrays.fill(result, -1); + + var queries = process(heights, originalQueries, result); + + List stack = new ArrayList<>(); + for (var i = heights.length - 1; i >= 0; --i) { + var size = stack.size(); + for (var q : queries.get(i)) { + var pos = search(stack, q.height); + if (pos < size && pos >= 0) { + result[q.index] = stack.get(pos).index; + } + } + + while (!stack.isEmpty() && stack.get(stack.size() - 1).height <= heights[i]) { + stack.remove(stack.size() - 1); + } + + stack.add(new Query(heights[i], i)); + } + + return result; + } +}