登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
### 多个数组求交集5 j: [5 L' u2 l0 D) B2 Y( W8 E
- ~7 V- W/ D4 P. m5 A) U3 b8 B6 R使用 Set 求交集即可。
8 G$ f& z" V* M' b4 e% Q
- ^4 n: O7 c2 W```Java
* Y7 v8 [; i# Z; k- G* `2 Iclass Solution {
" t$ T9 K% h: Z1 w ^ p public List<Integer> intersection(int[][] nums) { ?1 i k" w, D4 k/ ?' q4 i
List<Integer> result = new ArrayList<>();
$ O$ V5 s, @8 Z& O- s if (nums.length == 0) {2 z9 f3 H9 l- N; n- I$ s
return result;! R# z$ c) T. w, i5 l3 p
}% @* ^+ {/ `! v! c! U5 M
List<Integer> list = toList(nums[0]);. h( f7 v. I# p5 y& V- U
for (int i = 1; i < nums.length; i++) {
" I9 o9 s( t0 U- d list = intersection(list, toList(nums[i]));
( d& q4 R3 w# v! h8 e }
, w6 W: I, u& E8 U( v Collections.sort(list);
5 w) ?+ F$ S0 y return list;
3 o% I4 c' @4 w6 g* p, e" K } ?" ^( v4 v3 z: I, f9 B/ a
. m6 E! t z( Z- ~
private List<Integer> toList(int[] nums) {7 C1 i5 u' e* e1 |& [
List<Integer> list = new ArrayList<>();
4 l. O+ |2 Y G9 r5 T0 z. U4 I( ] for (int num : nums) {
" G6 W* G% I; y3 i list.add(num);% R" P" F2 s! T) r: @$ H
}' k! ]% u+ W" u: P- z
return list;
% ^; {9 U. E3 B/ K }
" m9 U$ F' N H8 k7 [& _
% s0 v& z; ^ i private List<Integer> intersection(List<Integer> list1, List<Integer> list2) {, R# R. C7 e. C3 e" j. s% ?
List<Integer> result = new ArrayList<>();
) w% z5 N- e3 p( w3 [7 ?' { Set<Integer> set = new HashSet<>(list1);+ l9 g* w7 B0 B! L8 Q9 j
for (int n : list2) {$ O' y' q* X3 s
if (set.contains(n)) {
4 d7 J0 V9 ~ e# I; \4 s result.add(n);4 a+ Q0 }; ~; I: g2 f7 B- q( Y; ~) k! O
set.remove(n);4 E. \; Y [1 C \5 E
}
4 O7 L' q. z3 F. ?2 ~8 Y! t }) D7 x5 P+ p+ |# x9 c
return result;1 n& m8 {$ K9 G. v) Y9 N
}
; r) ^5 g7 _, V}
# H* y8 j! C2 P1 A3 w```
4 c; k% [, K5 f
* U' L7 ]0 j+ b% T# F### 统计圆内格点数目
/ f* @" Y# W1 |% n
4 r5 Q! z3 q2 e! I枚举每个圆内的所有的点,将其加入到 Set 中,最后 Set 的大小即为圆内格点数目。2 \- t3 f" ]( B) R1 C- Q; t4 y
# K8 N( ?7 H% Z$ T( d```Java
$ J$ y. P1 o/ ?class Solution {- ?3 J; ^0 q. o* r- ~! b
public int countLatticePoints(int[][] circles) {
; V* p% s- s0 o' @; D: U/ i Set<Long> points = new HashSet<>();
/ X! e, i q3 \5 s for (int[] circle : circles) {: q% Y2 F2 g5 f! W7 V% a4 ^
int x = circle[0];& ^: g4 v0 S$ Q6 ]# h [
int y = circle[1];
6 P8 ]& N' w: f+ L' I4 _ int r = circle[2];
8 L# ?' }7 D: |+ X- J- N // 出于便利,直接枚举正方形区域,然后判断是否在圆内
3 z# x3 M6 O- z8 y for (int i = x - r; i <= x + r; i++) {
& c( N6 d; v& c for (int j = y - r; j <= y + r; j++) {
8 E+ e5 Q8 i2 U' ` if (Math.abs(i - x) * Math.abs(i - x) + Math.abs(j - y) * Math.abs(j - y) <= r * r) {
7 w6 H! U5 B) E' s points.add((long) i << 32 | j); // 使用 long 的高 32 位表示 x 坐标,低 32 位表示 y 坐标
2 D# _$ ~$ W: _6 N& s" ^ }
5 F: j' Q3 V5 A. u# Q1 { ` }
& S3 a% q- g% K/ d }$ @ z; j5 v5 V5 [7 F1 R3 b" ?
}4 J9 S/ N! f5 s2 u: f6 T' |9 u
return points.size();# h- x. j3 h* B1 h
}: U* Y: r3 E3 Y+ n$ X8 J
}. W& S; W2 ~) K5 k0 b3 D
```
- {4 H1 F; y- R0 j6 H; z; z4 B k, U% o; X* v! y6 H# K
### 统计包含每个点的矩形数目
6 q7 f7 m* C/ L2 N2 D
" f* g. x$ l( g" B: _与第四题类似,只不过变成了二维的。
0 x( A" o c( T$ v8 y
# \- I9 S9 E/ q0 \5 ?' D" D先离散化处理,然后使用树状数组实现 “区间加、单点查” 的能力。; C& T/ `: g, Q9 M5 D$ B
) ?& q2 P7 `5 U0 V7 }
```Java- I+ e* D4 i }4 T6 E4 O! x
class Solution {8 _9 M$ E- _3 r7 U8 U2 T
public int[] countRectangles(int[][] rectangles, int[][] points) {: r" d# r$ N" D, r* Z( \' d" x
List<Integer> xs = new ArrayList<>();3 J9 D; E: S w. y2 Q
for (int[] point : points) {
- t; g: \8 o7 `% i xs.add(point[0]);
& u: I9 M; L, L3 l }; f! X+ ^7 m9 E2 b+ U
for (int[] rectangle : rectangles) {
! a; J" f) k d( T+ J n xs.add(rectangle[0]);" {; l) k) _+ d- [& U
}' Q" x" r/ u8 O" t# D) M9 J
Collections.sort(xs);' q. p2 R- W" b$ P1 k- ^/ F
xs = new ArrayList<>(new LinkedHashSet<>(xs));# r, b; K" @1 G9 T& \. Y, s
Map<Integer, Integer> map = new HashMap<>();
5 E2 E9 ?: \, D1 b- p3 {2 i f) D. G for (int i = 0; i < xs.size(); i++) {
5 m2 P$ \0 l e/ ?2 A" \. i$ d/ S, a, s map.put(xs.get(i), i + 1); z+ f. e; x! N' [+ t) D% d
}& T: E9 ?8 M7 p7 j! @# K
for (int[] point : points) {
* L8 ]2 m' K5 Z, k/ k: Q | point[0] = map.get(point[0]);
& {0 v, `$ m6 J, i4 ~& U }. ?2 G! N! w2 ^7 l2 u# I: e" s: F5 V/ N
for (int[] rectangle : rectangles) {
, g1 S) o) K1 n' B/ h rectangle[0] = map.get(rectangle[0]);
, h: ^- c, d: q* ]8 v/ s) E; {+ B }! }% R2 z6 D; ?1 |) c' A& Q% p/ Z
int[][] g = new int[100005][105];! c8 Q8 I+ C6 f$ D4 F
for (int[] rectangle : rectangles) {
+ u; ~- r. G. j/ y6 h6 y `2 R& k add(1, 1, 1, g);: K2 i7 y! l" R( h
add(1, rectangle[1] + 1, -1, g);% M" F9 {8 U$ v
add(rectangle[0] + 1, 1, -1, g);
$ S0 V1 H. S4 E/ `1 @7 A+ k2 E add(rectangle[0] + 1, rectangle[1] + 1, 1, g);5 L, q3 r w" b# j
}- c! @% F! C; E- r) x7 o- [& @
int[] ans = new int[points.length];
0 y0 w6 ^! \4 f! f c for (int i = 0; i < points.length; i++) {( F0 _3 E/ p# W# j
ans[i] = sum(points[i][0], points[i][1], g);
3 a! D. o b8 a" T9 f0 H5 z }
+ D/ o5 [4 i! K) q* [ return ans;
1 `2 R" I! C: S1 _9 J2 M# |$ O }
' ]6 ]7 _6 { W8 d3 S/ i, o
0 p# H( O( r2 n: u6 B( W private void add(int x, int y, int d, int[][] g) {
- K6 w& A9 ^5 | while (x < g.length) {& ?: M; U6 o7 z) Z: }. {
for (int j = y; j < g[0].length; j += lowbit(j)) {; e4 T& P9 r# o8 ^8 ]- Y" t
g[x][j] += d;
6 L1 C6 I2 K. o' } }/ C/ _# G7 a, n6 z4 R
x += lowbit(x);/ C* h2 }: U3 w' U7 K
}
) k: g* r% r, n }
9 x# e8 D1 ?! I, k! w4 A, Q1 R z0 u7 n, F) k8 h! N0 ~) H
private int sum(int x, int y, int[][] g) {7 ?; e0 y2 J! G5 Z ~6 A# p5 J
int ans = 0;+ B7 U; Q& `$ Q6 S
while (x > 0) {' c) D) c, l, b. b, r* O1 O' x0 y! _7 P
for (int j = y; j > 0; j -= lowbit(j)) {# L$ d, g S. L3 H" M! C
ans += g[x][j];) m% L2 f$ b ?) L
}
" j9 n( }9 N- J' x4 s9 Y x -= lowbit(x);
& X0 `$ M7 m) `/ K. ` j }
0 n6 Q- E& s5 w2 A return ans;
$ _- P) u' n2 P; e" |4 G1 n8 I0 d" b }3 l7 T1 t; ~; j/ S
4 M# }5 ~& R- j9 O0 f( E private int lowbit(int x) {8 N2 p) _5 {3 d# k( j
return x & (-x);! J- B; d3 T, k
}
2 A5 o1 o( m6 w( c1 T$ W- L}
! v1 ~- @" T' \$ C```" b" |0 @# v- W* z, V
E: R9 @, e6 K1 g### 花期内花的数目) z0 y5 |% o& Q4 F8 y2 d8 a" `
$ C+ `2 A; ]/ O8 b0 s. B
首先进行离散化处理,`start[i]`, `end[i]`, `person[i]` 的原始数据范围都是 10^9, 实际上可以对他们进行压缩,也并不影响正确性。
1 E! O* l# ?& S- G0 x
, S1 d9 @/ E+ q( k比如 `[[5, 10], [100, 200]], [1, 2, 3]` 可以被压缩成 `[[4, 5], [6, 7]], [1, 2, 3]`。% d0 g. R; k: o4 ?2 [+ G4 a5 I8 Q5 Q
, {; a* N7 Q" } N, z b
压缩后我们使用树状数组实现 “区间加、单点查” 的功能,即支持如下两种操作:' e1 h7 B/ Z; Q( S: G
4 E) K n; w1 G8 y. u: h- W/ [- 给区间 `[l, r]` 加上 `d`# t" g) T- x& `! F7 S' D2 N
- 求点 `x` 的值
- N6 [- f b3 ~$ c6 O3 V4 a- `3 [: {. J8 [! @
相当于使用树状数组维护 flowers 的差分数组的前缀和。7 c8 t) R; W+ l/ |$ |5 d" |
9 d: l) W$ O, A0 |4 m; B9 O: D```java
( U" g0 i' \" J" Jclass Solution { s5 d. d( r: ^. l
public int[] fullBloomFlowers(int[][] flowers, int[] persons) {
; E$ K: E$ n1 a5 d9 k j# f TreeSet<Integer> numSet = new TreeSet<>();7 B. j; \. @% \* y) Q, Q' G8 m5 m
for (int[] flower : flowers) {+ k1 ?; [4 m, O1 g
numSet.add(flower[0]);+ B! l {. O+ I
numSet.add(flower[1]);
' k5 C' z7 I; i3 {% o }
& `" R( @0 m8 `# G# M for (int person : persons) {+ R2 }8 [2 L# }3 w! |9 z
numSet.add(person);
2 R- F, ~" L( B: x1 f+ @( f# @9 C }
; ]. w# H2 @3 g4 X, M Map<Integer, Integer> numMap = new HashMap<>();" W$ r, g* y2 k( D
for (int num : numSet) {5 ?3 t$ S; t$ W Q7 X
numMap.put(num, numMap.size() + 1);
N/ T) p9 D3 s2 k, Y }
7 ~ D0 z: ?" U* E8 c2 G for (int[] flower : flowers) {; r" C" t( b* Y
flower[0] = numMap.get(flower[0]);
( I2 a: n% ^0 G; ]' q$ v flower[1] = numMap.get(flower[1]);1 M, O5 J- o9 R+ W5 C4 Z4 N
}
" E# ~ X$ q; e9 S0 z for (int i = 0; i < persons.length; i++) {1 S3 `. I; `* k' [: c
persons[i] = numMap.get(persons[i]);
d& ` H/ d. g5 c6 [! [ }0 m# Z# U& w/ X0 Y( w% d3 T
// 区间加和,单点查询2 v+ Z2 z+ D1 e4 z# n' ]1 V& k
int[] sum = new int[numMap.size() + 5];
" D' |: f0 `) ?9 O$ J for (int[] flower : flowers) {& h1 u1 j! ]6 a: [7 S, \
add(sum, flower[0], 1);4 _" ?* ]. L" E4 y" t0 X" p3 X
add(sum, flower[1] + 1, -1);
9 p4 q) P+ N+ {4 `# `# } }
7 }8 }5 X9 K1 L4 i- ~% Q/ m; P int[] res = new int[persons.length];
, r4 h2 `/ d$ M( G for (int i = 0; i < persons.length; i++) {8 _9 P- ^. J i1 t
res[i] = sum(sum, persons[i]);
. c% P* i1 V5 K6 h/ i }2 s _4 J" s: ]- B W% \/ L
return res;* a7 d0 e+ |) e" U2 `& ?/ A
}5 T( h. Z8 L+ v W. l! ~
1 i* y$ s" Y$ q+ \4 Q5 X
private int sum(int[] sum, int x) {
/ v) E5 T7 M/ r# E; k int res = 0;/ I ]9 F/ Q2 t) q7 c
while (x > 0) {
$ K" L8 M t- s res += sum[x];% W1 r: `6 w9 }6 ]. i( C5 \) {
x -= lowbit(x);+ f( j) r& r) ^" ]0 O
}) y4 w' s/ C% m1 K0 \
return res;
0 r; k8 b. j* V" x! o# L. L }5 E( }+ {4 n0 [- r$ P1 u
6 p, z1 S/ O H l* G" i
private void add(int[] sum, int x, int val) { L/ B6 C3 V* D% U% R$ B0 ]; c+ N
while (x < sum.length) {
$ N' U! g8 n/ E( l2 J1 Q4 J) G! x sum[x] += val;+ O* [9 k+ c e1 u3 r# b: [$ P- l
x += lowbit(x);
, F- k. ]; p% k0 a! L% q, b4 x, v( t }
" z: b- r! |6 U0 y" R }
3 ^3 K1 b5 h( x' j
. G7 U( V$ w- c/ p! B) N! G& x- m private int lowbit(int x) {
% Q5 `9 m" [2 C; G6 f1 H2 }/ B return x & (-x);! F% Z! ]1 R1 N' q5 I& A& O5 F
}9 T5 e" _' [* D9 H3 h7 u' s& m8 t
}
2 s6 D$ k! |1 C: S1 r9 t2 N$ K- q |