登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】$ L1 ?: r; |) \7 h5 h
解题思路- m) W7 w7 L: w2 o$ w
签到题,循环判断即可。
: a" ?# G$ R5 o3 Y: G& N8 |( O& j) A4 b' |2 i
代码展示3 _4 r/ d3 Q+ R/ t) h% ?
* x" [' I* S$ {6 b8 B& ?
class Solution {
6 R& V# O3 c! ~, L3 ^ public List<Integer> targetIndices(int[] nums, int target) {' w4 k; j L" K5 M' q# Y9 P
Arrays.sort(nums);
& l7 J; r5 a! C( [ h List<Integer> res = new ArrayList<>();
& j8 w4 b, N3 w3 L ^9 }% R4 m$ f for (int i = 0; i < nums.length; i++) {9 l3 `$ Y- a) x# h6 z/ e, d
if (nums[i] == target) {
* s) F9 x7 ? u) T" ]; b res.add(i);! r) G+ R8 j' |3 [4 T" S
}
0 E: e3 u8 _5 O$ F }* g: L3 P6 p0 A& S& J6 u* ?
return res;
) \* H: B! c+ c }7 e6 _% G' R4 B8 i. j. R7 Q- I
}; L/ T- F0 S( N1 w
& D4 K9 i5 d# E5 U G) L$ K7 s
【 NO.2 半径为 k 的子数组平均值】
/ P1 ^1 @, f/ G解题思路0 H7 I* U. z1 Q5 i) s! w0 i
使用前缀和计算区间和。注意使用 long 类型以避免溢出。% b C! F& C, }3 b5 [
9 g4 }1 Z. h7 a代码展示, K+ }" E$ u3 _5 N, q0 P# {, N
+ z% y6 m) M( X! d1 O
class Solution {( R% ^( ~: ~$ W2 r+ k8 F7 h' v+ O
public int[] getAverages(int[] nums, int k) {2 Z, U' _4 W! \1 V' I l
if (k == 0) {1 r+ j A, R( `9 N# U0 |8 c% v
return nums;- }2 t; v- M1 @$ M) |0 c
}
L! J: s3 I' i, w0 \# P3 ?) ? long[] preSum = new long[nums.length];5 t5 z* Z& J% S8 k5 g, J0 ]5 v) l
preSum[0] = nums[0];
9 h6 x4 f6 G/ W4 i& I- M7 C. v$ U# z for (int i = 1; i < nums.length; i++) {5 G$ y9 v% T3 b+ I( |: e5 y
preSum[i] = preSum[i - 1] + nums[i];
% h& N! G/ t7 G' @, Z }) s* n9 N, o! z# Y4 \% ^) p( x
int[] res = new int[nums.length];' M+ _! D4 K4 ^
Arrays.fill(res, -1);/ K" I; P% N8 J0 x, V2 v- g
for (int i = k; i + k < nums.length; i++) {
/ }0 _. a' ? }( a long sum = 0;
2 V4 J( y) M/ B! P7 r' M if (i - k == 0) {
b1 w+ Q; ]: ?% v; H sum = preSum[i + k];
& N/ Z4 J+ [ Z+ i# J5 N } else {
( z& G- C H, y3 W: _; q sum = preSum[i + k] - preSum[i - k - 1]; K# g: Y G2 `2 K
}
+ W" Z+ I2 e2 q# p; X res[i] = (int) (sum / (long) (k * 2 + 1));
; I/ f8 l! x, R: k% f }2 A6 m( R, ?& m+ v3 R! Z! W& h6 V
return res;
( ]* I0 [* E! B1 ?2 F }
6 Z. G3 |4 G5 [: a- _( O( u}
4 o! F1 W+ Q$ B+ ]2 I7 J& n- v T0 N3 `- ~
【 NO.3 从数组中移除最大值和最小值】# \+ {& B0 E% ~# [
8 b) s% \8 |2 u/ l1 b h解题思路
: l7 s0 @/ L$ u" ]9 z+ L4 b贪心,按照最小的花费移除即可。详见注释。5 I f( N' ?' ~, H& W' Y
, l! h0 n* I) r% K代码展示/ I5 C$ x) J* m5 r
$ j5 c/ Q& y, B; a+ v" D6 I0 {: Rclass Solution {
4 T7 {2 h7 F1 A2 S public int minimumDeletions(int[] nums) {
4 ~' W) O" t, A; A; R( n if (nums.length <= 2) {
6 b/ j/ ~9 W7 k return nums.length;
: v8 x. v# S- K" { }
( S/ F1 x' E r# f9 x% V$ ? // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
1 I# R/ m) O6 T int min = 0, max = 0;& h3 |( K4 C& S& a
for (int i = 1; i < nums.length; i++) {
1 A0 p+ j! }; m if (nums[i] < nums[min]) {: m# v8 n1 k& f! B9 c( x
min = i;
1 R0 R: X- O. j2 E7 {0 v2 c: p+ S; A( t p! N }% `7 `/ R7 U- B' s! S# P4 W
if (nums[i] > nums[max]) {' C1 i5 [ \1 g/ m
max = i;8 v- l% j0 v. G
}
! @0 d) J/ ], @% D3 h. @. f }
* \# J+ x( @; G, @1 E // 要移除的元素下标为 max 和 min4 D- `$ W) P% D2 g3 f
// 此时我们只关心下标,谁是最大值谁是最小值不重要" F6 h, _9 [. ~5 k
// 为了方便处理,令 min 为较小的下标
3 @0 Z: ~: B4 z+ |- m; `7 A if (min > max) {
. a8 t: U: q* t( x int t = min;- J# }) U5 ]$ y( t
min = max;3 x- w* a7 y9 u6 x- q2 ~
max = t;
. y }' s J3 i& E* s; r( P. i }; |7 T' ~9 D; R* ]! ], O
int res = 0;4 P6 S0 f# `( G& H1 {7 `
int left = 0, right = nums.length - 1;2 M7 _: ^( S1 s- M/ P5 {
if (min - left + 1 < right - max + 1) {
/ b$ \8 s1 C/ F7 l. o- @ A, E! c) V! H res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
0 m! E: s6 ^# d% F6 `1 l left = min + 1;. W0 G2 k) _ K7 o4 i
res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
& j P/ F: K# w% r) S" }) Y } else {
. `- i3 _7 W! R' O# w/ B res += right - max + 1;. z# o7 n; k# M% j( z- f6 Q
right = max - 1;
- D( ^+ k. `- g5 O res += Math.min(min - left + 1, right - min + 1);! s1 c" w1 \+ z& p2 M
! ]* Q; j/ Q8 H# x
}; S0 n/ H0 I5 f8 M: q
return res;, A6 Q# u' v5 K4 M" \" m
}
4 b5 Z+ [ }- E$ O% P/ r. T4 V}( S4 N# t9 M1 u. w
- r x* l, U; o6 x3 k1 K【 NO.4 找出知晓秘密的所有专家】- _6 i$ Q0 F8 Y$ }; r: j6 S6 o
3 x& g2 e+ o6 R4 b
解题思路& D4 w) X. ~; u
并查集,详见注释。
3 O. k7 D: ?+ S# ?2 _# H4 r# J4 }5 W# X/ R" x
代码展示1 h* P9 O; D8 W4 e6 H6 T% J
) M8 n7 b, n8 q+ | ~
class Solution {' k4 e9 w# p+ s
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
/ |: n" T6 T7 ^ // 按照时间点将会议分组0 F0 q" X* h0 E C2 _' A
TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();9 ?% x1 V# b' a* D/ U
for (var m : meetings) {" }( n# O4 e6 u
if (!orderedMeetings.containsKey(m[2])) {
/ l# V: u+ d* y2 @+ l orderedMeetings.put(m[2], new ArrayList<>());% @+ p% y. d, q
}1 A7 e9 T$ r* b" w4 X
orderedMeetings.get(m[2]).add(m);
/ A) H' H0 o! v$ T- P0 `5 B' i1 J- A }* W; a4 o% o9 x; _" Q2 [
boolean[] known = new boolean[n];
) }+ \# n3 f9 R5 B! W9 D! a known[0] = known[firstPerson] = true;
6 L4 e/ k Y8 H: |$ ` while (!orderedMeetings.isEmpty()) {7 \2 p& ?, l ~% y* [$ |
// 按照时间顺序处理每一波会议
2 k, r' F8 S- Y& b# n var entry = orderedMeetings.pollFirstEntry();% Y/ Y# v, I6 y+ H; Z
var curMeetings = entry.getValue();
; j( K- t' ~$ M* T // 使用并查集维护当前时间点发生的所有会议中,有关联的人
. y$ X; R2 M% d UnionFind uf = new UnionFind(n);$ M, c& G+ r( u! H2 t# v
for (var m : curMeetings) {
! U/ e5 [0 A5 h; ?6 H uf.merge(m[0], m[1]);# }- t4 m# \% B% l! H
}
8 \+ g ~( i' [ // 枚举所有会议
8 m" Y; R c) \# `5 W' y // 若会议参加人 m[0] 或 m[1] 知晓秘密
+ R7 M0 ?$ R U5 y0 ?/ t0 P6 m // 则把他们所在的根节点也标记为知晓秘密
% W( z/ v$ D6 Y2 T) Q( K for (var m : curMeetings) {
" i3 K$ {5 s7 H' S0 \" K1 |4 A if (known[m[0]] || known[m[1]]) { W; h9 f; H+ B/ c7 |5 _
known[uf.find(m[0])] = true;/ ~* u' n9 a# \0 R
known[uf.find(m[1])] = true;
& v& H) T3 I$ M ?+ P- ` }
/ W% d p; y3 _* M" I, m5 J }
, {0 S, g9 l0 q& T8 f0 v: C b // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
1 H8 }+ D8 z1 J9 Z for (var m : curMeetings) {
. d; A# G% g/ m& s: ^ if (known[uf.find(m[0])] || known[uf.find(m[1])]) {% y3 [# x' s+ r! L! f, J: p2 _
known[m[0]] = true;4 D8 i: H3 B5 z8 L$ s
known[m[1]] = true;2 T' s+ q; P2 a5 q7 C: N, s9 O# z
}" ~' J" J7 g/ {4 M& v
}
# Q7 X5 t7 c e5 s2 g3 ] }" C) n) a* ~3 i8 v2 z- F
List<Integer> res = new ArrayList<>();" K7 L" D* K! \' U8 d' k. e+ `
for (int i = 0; i < n; i++) {
6 |5 z8 N3 |$ k5 b' Z( ^9 L if (known[i]) {- D Q0 k- I" V O/ D4 W
res.add(i);
! j: m: n4 v3 }4 }! r }
8 p D) e9 ?" n& {+ D8 ?/ M }- U# d) x1 w$ _2 q6 E& ?
return res;
5 |4 L" _) ]( E1 b" u: C- a }( M% j: O3 g* {. M9 R0 R( o6 o
}
6 F8 |- h6 Y; A2 N' k
- r# M2 g4 ~- k$ Wclass UnionFind {
- n* K+ I: e( F: Q1 P, a3 c. i+ } public UnionFind(int size) {
* ?" m, G8 ?5 H( _% H4 f f = new int[size];$ D9 E5 ]* B4 h2 H& H% a; T
Arrays.fill(f, -1);- |, J* ~3 I. l% [+ e2 ?! z
}
1 e' h( Q/ H/ H( Y6 Y: U4 z
9 R* X4 K9 e3 n! N# m public int find(int x) {6 ~* T; T, s0 r$ _" B, j F% j
if (f[x] < 0)6 o$ Y% x( X! t B
return x;
. D7 k8 c ^* e! \2 @( \ return f[x] = find(f[x]);5 L# N+ j; q) S! W% d
}5 k( ]5 Y- H5 U4 p
0 R! Q) g/ k) z3 S: E4 \; ]) m# } public boolean merge(int a, int b) {
1 l0 ]+ b% ]( s int fa = find(a);
- S2 n) t7 U8 O' a0 I int fb = find(b);9 I0 Q7 b7 \; v9 n+ f5 M% D
if (fa == fb)
; x+ s* |) a* ]8 Y L& K return false;* q3 Z! K7 c" z
f[fa] = fb;; b' i! g- c- ^% w. ]8 e# |
return true;
7 u5 O9 z% p: `8 N3 u$ G$ n1 [ }0 W' _! F# f# ?! X. w1 z
/ q# {; |$ G X$ u* Y: B I& V( C public Map<Integer, List<Integer>> sets() {' j! r& f0 o( q9 u! b2 v5 a+ w/ y& \
Map<Integer, List<Integer>> res = new HashMap<>();
# l( i1 f' Q/ F# A for (int i = 0; i < f.length; i++) {8 S7 C/ c9 Y. \# A- w
int fi = find(i);
0 P' z* L7 R a3 Q if (!res.containsKey(fi)) {* ~/ d3 @9 J: T
res.put(fi, new ArrayList<>());
; z2 }$ m6 i F& ~ }
8 u; c0 }/ V0 B' k, y+ @; K res.get(fi).add(i);
+ U1 N W3 c8 d/ [ }. H! @. s+ v& u0 d$ S6 V
return res;: L0 T, a- |) X1 a$ }
}0 ^+ B: O9 [/ T/ I; ^
0 {. ^$ W8 }. V9 s' I: l& W
private int[] f;% {6 J$ K2 e0 B' Y
}
6 x- d* C0 Z n9 q9 {, Q |