We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
一、 思路
这道题如果简单地使用两次遍历,O(n^2)的时间复杂度,会超时。从题目条件1 <= rectangles.length, points.length <= 5 * 10^4可以看出端倪,数据最大可以达到亿级别。
所以需要优化成O(nlgn)之类的复杂度,这就要使用到二分法或者分治法了。我们从题目条件发现x的范围很大,所以可以对x进行排序后二分,找到大于point的y坐标的矩阵边角,对于y我们可以排序聚合。
以下是上述做法:
class Solution { public int[] countRectangles(int[][] rectangles, int[][] points) { int[] res = new int[points.length]; int max = Integer.MIN_VALUE; TreeMap<Integer, List<Integer>> map = new TreeMap<>(); for (int[] rectangle : rectangles) { if (!map.containsKey(rectangle[1])) { map.put(rectangle[1], new ArrayList<>()); } List<Integer> list = map.get(rectangle[1]); list.add(rectangle[0]); max = Math.max(max, rectangle[1]); } for (int key : map.keySet()) { List<Integer> list = map.get(key); list.sort(Comparator.comparingInt(a -> a)); } for (int j = 0; j < points.length; ++j) { int cnt = 0; if (points[j][1] > max) { continue; } for (int key : map.subMap(points[j][1], max + 1).keySet()) { if (key < points[j][1]) { continue; } List<Integer> list = map.get(key); int size = list.size(); int l = 0, r = size - 1; int flag = -1; while (l <= r) { int mid = l + (r - l) / 2; if (list.get(mid) < points[j][0]) { l = mid + 1; } else { flag = mid; r = mid - 1; } } if (flag < 0) { continue; } cnt += (size - flag); } res[j] = cnt; } return res; } }
第二个做法是对points和rectangles排序,然后计算每个rectangle内部节点的出现次数,最后遍历points,查出对应的出现次数。首先需要对两者共同排序,先对x坐标从小到大排序,接着按照rectangle -> point的顺序排序,这样能够保证每个point之前的rectangle包围的点的出现次数不会漏掉。这样就绕开了数据范围较大的横坐标,直接对y坐标进行计算。
class Solution { public int[] countRectangles(int[][] rectangles, int[][] points) { int n = rectangles.length, Q = points.length; int[][] es = new int[n + Q][]; for (int i = 0; i < n; i++) { es[i] = rectangles[i]; } for (int i = 0; i < Q; i++) { es[n + i] = new int[]{points[i][0], points[i][1], i}; } Arrays.sort(es, (x, y) -> { if (x[0] != y[0]) { return -(x[0] - y[0]); } return x.length - y.length; }); int[] ct = new int[101]; int[] ans = new int[Q]; for (int[] e : es) { if (e.length == 2) { for (int i = 0; i <= e[1]; i++) { ct[i]++; } } else { ans[e[2]] = ct[e[1]]; } } return ans; } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一、 思路
这道题如果简单地使用两次遍历,O(n^2)的时间复杂度,会超时。从题目条件1 <= rectangles.length, points.length <= 5 * 10^4可以看出端倪,数据最大可以达到亿级别。
所以需要优化成O(nlgn)之类的复杂度,这就要使用到二分法或者分治法了。我们从题目条件发现x的范围很大,所以可以对x进行排序后二分,找到大于point的y坐标的矩阵边角,对于y我们可以排序聚合。
以下是上述做法:
第二个做法是对points和rectangles排序,然后计算每个rectangle内部节点的出现次数,最后遍历points,查出对应的出现次数。首先需要对两者共同排序,先对x坐标从小到大排序,接着按照rectangle -> point的顺序排序,这样能够保证每个point之前的rectangle包围的点的出现次数不会漏掉。这样就绕开了数据范围较大的横坐标,直接对y坐标进行计算。
The text was updated successfully, but these errors were encountered: