登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】' M) u* m2 z. B0 R( c
解题思路
. Y. [& H( I' g4 r2 e6 A签到题,循环判断即可。3 ]5 l3 e' `" Q; h5 v1 ?0 S
2 {& H0 v# {* k! N/ K& Y# M
代码展示( K# q. O9 N/ K# s: K* L3 R b
: _$ a3 x6 I2 ?$ f3 nclass Solution {3 b; C/ q: Y! t$ J" F2 Y" ~* l5 ^
public List<Integer> targetIndices(int[] nums, int target) {
# M3 N, T2 G+ _! \ Arrays.sort(nums);
# ^& T- b1 T2 V% j3 a5 V/ ] List<Integer> res = new ArrayList<>();; Q& k* }& g5 d* J w. t
for (int i = 0; i < nums.length; i++) {
/ j+ X, c/ R! g" w3 s; P if (nums[i] == target) {
3 [: l! P- |) g. p) J# G" ? res.add(i);
( Z/ R7 s X3 P }
0 h* z) h' U4 _5 o/ a- E7 M' M/ ] }
1 H6 W, Y0 o4 T) o" B. C return res;
) M3 D3 g6 @3 L: o }
2 I# F1 j* Z: A& Q" r6 P! j}- O: ]1 @' j [4 s
" n3 W* ?4 O# k0 i; T2 @ z【 NO.2 半径为 k 的子数组平均值】
8 t# Z H5 j1 T1 B- S+ l$ U- y解题思路
- Y; D6 R" d5 X$ m使用前缀和计算区间和。注意使用 long 类型以避免溢出。$ d+ n7 z ^' J- m+ r9 }0 _9 N
/ e7 [; ]1 c. A0 o4 T9 ?1 g: U代码展示: M y t' B$ ^
) F- j2 L; y/ }" l
class Solution {, @" \8 j6 `8 H2 t$ D
public int[] getAverages(int[] nums, int k) {4 X5 d% v& Z9 A6 z# O, {% {, d' E( y
if (k == 0) {
8 k1 G8 e4 F7 k* _ return nums;7 c6 N1 r: |) n: F
}) g( X8 r0 e D5 `
long[] preSum = new long[nums.length];3 W! }( A! B" U# e
preSum[0] = nums[0];2 X: e7 @7 |* Z+ h3 {- v
for (int i = 1; i < nums.length; i++) {; H; J3 V8 h1 s0 t3 U6 P
preSum[i] = preSum[i - 1] + nums[i];
1 z0 m1 ~! k. J }
8 k$ P2 T w- A5 H3 `8 c int[] res = new int[nums.length];
; d8 Q/ W# A- D; Y Arrays.fill(res, -1);
2 h8 V7 B/ |. U3 E" ?: V1 b. i for (int i = k; i + k < nums.length; i++) {3 c0 r& s) a; ]$ @+ g- [* e
long sum = 0;
0 v8 a6 m3 q3 i5 \* \ if (i - k == 0) {
/ |3 v7 y1 y! y! D sum = preSum[i + k];9 N8 @ s( N8 q/ F$ A) x$ J
} else {
. v3 F% D& Z; w0 k" B, M. K4 P { sum = preSum[i + k] - preSum[i - k - 1];
- h5 L% {3 n* \6 D2 R5 F }. x( @! H7 {5 b$ E3 b5 w7 p/ V
res[i] = (int) (sum / (long) (k * 2 + 1)); M3 y8 N( j$ ^/ \, y2 ]
} c, R0 z! V1 v% r9 A% R) N
return res;3 R, J& C- S8 @, J6 S
}, G& y7 H h! i* C! O
}# S+ ^, h* J$ K8 u* g6 V0 f
7 T0 J1 {) ?# {, T; v& ?
【 NO.3 从数组中移除最大值和最小值】" N* R: H' o# |* @
5 D+ R" a. _7 q+ A4 j2 Y; Q: ^
解题思路
4 i9 ~+ P1 T7 ?7 l- m* X6 f( l贪心,按照最小的花费移除即可。详见注释。
8 ~$ z" O' ]5 ?+ J9 l- M9 P! M; a
7 s4 i, [! d- g2 a+ N: d6 F/ J代码展示
0 d0 s& k/ T; `6 t/ z5 M; Y4 Y$ P
: ]1 I5 [6 ^! N, x" g' Iclass Solution {' Q c6 j. b$ }. j' h
public int minimumDeletions(int[] nums) {4 [, {' `6 c, e$ F9 }% l
if (nums.length <= 2) {! J- ?3 e0 s, `! U. y/ p
return nums.length;
* v- ?1 H/ e3 B/ K' I6 b' ~ } ~1 {% P g5 ^; R' _
// 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
5 X( T. t$ ~2 ~ int min = 0, max = 0;4 l/ k g5 p& L# ^( t0 C
for (int i = 1; i < nums.length; i++) {2 f2 N) J7 L y( i
if (nums[i] < nums[min]) {, l( I1 O2 ^6 R
min = i;
: ?0 |) _* M4 f9 q0 E% O3 b; T) M }1 Y! f* C6 O" L5 \5 I$ u
if (nums[i] > nums[max]) {8 i. ~) \1 i l# X& O
max = i;
2 C. ~6 P: |' \ }
) D0 I2 p* J% v# i/ ~) k }
a7 l5 } I% M! L: O8 d2 z // 要移除的元素下标为 max 和 min- K: K$ P" x7 r+ p' |* Y
// 此时我们只关心下标,谁是最大值谁是最小值不重要
. |, ^5 {# ]$ @/ I // 为了方便处理,令 min 为较小的下标
6 a! F. |+ z% A if (min > max) {$ H8 E' D5 f" `5 G
int t = min;' s- a' i8 P+ r x* d' i" ^
min = max;
0 Z4 X e% X; s3 Z' U max = t;
; s/ Z0 x" i6 K; Z# T- i- i7 w: I* N }$ D+ T/ n. K' k- Y$ K o
int res = 0;
" G! u) W5 B0 P3 x0 ~ int left = 0, right = nums.length - 1;2 K9 H- r! Q8 q9 }+ `5 N; o4 G
if (min - left + 1 < right - max + 1) {
; b3 R1 ]" [: g) U$ _$ X; `9 F res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
" o- v- d. w7 X' _& n left = min + 1;
1 D1 ?- q9 C! q4 g: O B res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
& o' {2 Y( U9 ? s } else {# B) p, }# g: l7 n3 c" K% N
res += right - max + 1;
4 z3 R# P6 ^3 E) v right = max - 1;( p' o& F) ]3 T/ X1 J' x
res += Math.min(min - left + 1, right - min + 1);
7 R5 j+ }, b/ d* H& D$ n! b
! z' B0 n; }; ?6 q- [$ ]- g. O }
: \2 o$ P; p# s/ J1 _ return res;* l4 @0 u8 O: r5 l1 i" k& V( v
}4 C: u. g/ d9 j7 L: a# o1 J
}
8 W' S: P! X8 D2 v$ l# o- W" J0 {2 `. C# Y
【 NO.4 找出知晓秘密的所有专家】 `5 n! b6 C0 d/ N4 D
i6 I$ K+ g. e1 C: Y1 V/ v2 @
解题思路
9 ~: U6 C# N' J# q. ]并查集,详见注释。
+ @: t) L8 }1 ^4 s5 {: u k
6 w7 c7 `. f* E" }5 n- s代码展示 j, u4 N7 e, f {+ D1 h: O# P
6 p" Q0 h6 M# [0 y) Tclass Solution {
+ P9 B/ N+ p- Q5 i& b- E public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {: g/ K; M4 G4 @1 E
// 按照时间点将会议分组5 A4 ?5 I# N+ M3 A
TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
/ s' c$ D, Y. d* Z- W" `: }! k for (var m : meetings) {
$ r' P0 K7 b* b! M0 `* N if (!orderedMeetings.containsKey(m[2])) {% y" F0 W0 P. @- r
orderedMeetings.put(m[2], new ArrayList<>());8 }, q$ q* A& ?' R: r
}% R" x; H7 F4 Z4 g4 s' x
orderedMeetings.get(m[2]).add(m);
+ h3 P C$ ^: F* W c! W }
+ |: p+ e! U' ? boolean[] known = new boolean[n];3 [7 ^7 [9 ^* n7 b2 E
known[0] = known[firstPerson] = true;; g' h( L0 L( C
while (!orderedMeetings.isEmpty()) {6 y9 G0 a0 y* y+ Y4 @
// 按照时间顺序处理每一波会议 Y* @# L3 B. V3 H# x
var entry = orderedMeetings.pollFirstEntry();" M1 D1 A% Z4 N" ]9 A2 V( C9 ?
var curMeetings = entry.getValue();* j$ _: D* ^1 A8 u% s( ~
// 使用并查集维护当前时间点发生的所有会议中,有关联的人
$ Q& s# _3 A: v4 h UnionFind uf = new UnionFind(n);
# P, h6 ~9 U, c* _% h for (var m : curMeetings) {8 U# P& n# r" A
uf.merge(m[0], m[1]);
! c( B+ A. ^' r, B4 v }+ B+ J+ U1 m% ? w1 U( M
// 枚举所有会议, _7 y9 Y+ E) I2 b7 u% M, s
// 若会议参加人 m[0] 或 m[1] 知晓秘密
* J* K. e. e3 Y- z3 L6 S // 则把他们所在的根节点也标记为知晓秘密$ A9 J' s b/ i+ t; j: s2 U# I" H, b
for (var m : curMeetings) {
% j( q4 B1 |/ b" S% L if (known[m[0]] || known[m[1]]) {
3 [* l5 s2 ^2 M- s/ y known[uf.find(m[0])] = true;- e$ E+ Z0 { d# h
known[uf.find(m[1])] = true;0 k5 G. S+ M$ r1 s3 I6 L& c0 R
}8 S& D/ X' s! ~. F* w1 U( L0 C( B
}
) B" _' ~0 J: z& n" R0 W // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
1 D, Q+ D* V: V, X6 ^! F/ k for (var m : curMeetings) {: K7 R, a- f" H
if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
7 q& h. S; v3 h known[m[0]] = true;
6 g5 z1 }' G6 U5 ?- _" U known[m[1]] = true;/ |8 Z. \! C1 E6 E" T( m& [2 q
}7 S+ `4 ^% ~, Y& G4 o9 s& e* _ L
}
( ]. }; [" V5 F) `' V7 ] }
( A$ n: p. v, t/ T3 k$ C7 n' j( f List<Integer> res = new ArrayList<>(); E0 o, Q; j, J! C! R9 \1 K
for (int i = 0; i < n; i++) {
7 D; ^! |' o! M7 x$ L0 m% T if (known[i]) {
+ \! |( G3 N' N$ V2 P* \1 ` res.add(i);
# Q/ L' n5 g" u& T. T0 \9 o }
: d( |0 r) g! l5 O! }1 E' s) [ }1 j2 \% I9 r/ g: l6 `/ c
return res;
$ U. j4 Z3 D) \3 @9 e& s }
- d8 _+ w4 x. a" T" B- j; u}0 u! q& F2 R8 |, v: p6 h5 B2 v0 n
2 s6 X, N; e& v6 K7 i( r: vclass UnionFind {4 l+ g3 Q6 g5 b/ V% d- Y
public UnionFind(int size) {' C- p0 F+ K! D% \/ b5 T) C: [
f = new int[size];
1 H8 _5 O- C7 @+ ], G" ]! r Arrays.fill(f, -1);
# J5 D( ?0 B$ @- A' }! Z }
1 W2 s& d3 j [/ f
7 M* g" X# r: Q0 M2 K* U' P public int find(int x) {
/ J5 g3 V \7 K% ~ if (f[x] < 0)# ~" T* j! P4 u9 o9 U7 h7 E
return x;
& j3 a: I2 Z# |6 |# a return f[x] = find(f[x]);
3 \# d; x8 w2 f% b B! g3 i% y }! g7 ~/ w! M. y1 e9 N: Z
, j4 M6 D W! ]6 `" \, N0 ]# q
public boolean merge(int a, int b) {" c _; ]' B, H0 O
int fa = find(a);1 ]/ X/ R" k4 H- \! R8 h- D
int fb = find(b);' ], \/ |* m8 n3 F) u# }6 A& O
if (fa == fb)# Z6 ^! L7 T# z" f
return false;
_. e5 ]# m L9 Y f[fa] = fb;
! t8 t+ O# c R* J5 ] return true;" A9 C* J4 M; t/ a5 i
}$ \0 l3 W9 C( z+ a3 t
- \3 ]) q5 R3 I public Map<Integer, List<Integer>> sets() {
3 Q; E! Z9 D" J A7 O) k Map<Integer, List<Integer>> res = new HashMap<>();
9 m( K1 ~' K+ H- W4 H/ c for (int i = 0; i < f.length; i++) {
8 _& t6 @6 x% W5 B/ q) ^1 n int fi = find(i);( O7 `; Y! b$ O5 R
if (!res.containsKey(fi)) {
q0 O- R6 f7 ~4 G, v9 N res.put(fi, new ArrayList<>());
- q8 u2 D% v3 a; Z5 W$ s }
m( k5 w) D3 B5 q7 ` I( M res.get(fi).add(i);0 ~& b, |+ x' f- j9 a0 ~
}! Z: ^9 ~8 [; a
return res;
6 `3 q( h0 U) Y" G6 h }
2 p+ Q+ H* T- J7 u" K, u7 v
( r" ~2 C f/ r& C private int[] f;: F4 b4 V+ ?. l+ J* N
}7 k! _/ g. T$ Z2 u! ]& l3 D$ I% V
|