登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】
" [- n7 A$ g( Q解题思路 l; j6 m0 L* A, R4 b
签到题,循环判断即可。2 R9 v8 p" |, Z N1 l
% A% o: X+ n5 B3 S代码展示
& l- {! {0 i: L3 s
2 V: W( j9 ~/ {% m" Q& P5 Eclass Solution {2 `& g2 x1 k0 r7 }' g, U
public List<Integer> targetIndices(int[] nums, int target) {
( B( s. L2 \8 z7 P Arrays.sort(nums);
! s+ C1 }3 K& |+ a9 _# Z List<Integer> res = new ArrayList<>();
* ^7 _/ I4 I4 I/ ]2 Q for (int i = 0; i < nums.length; i++) {& ~% S) @: k4 h: Y
if (nums[i] == target) {, [0 H2 D' u( d
res.add(i);
8 L$ l4 h: J' _! @; X' O2 e }
( J! X% [4 o3 k* e+ t* Y3 F }
; ~! e( y& r! h9 b5 X7 f6 \* }/ |9 b- G return res;
5 ^7 k) @/ i7 D8 x7 J2 C2 J }
1 h! `- {5 s N+ Z6 t) B( ~0 u}( O7 a! S) p. a0 j4 I1 h- y5 h
' E9 w( K3 k d/ q" i! B【 NO.2 半径为 k 的子数组平均值】
1 j! X3 q! v; ~: U& [解题思路. h; P) b; {/ a9 D- Z, C
使用前缀和计算区间和。注意使用 long 类型以避免溢出。& d: }+ G. O% y# P& O7 k* ~: b# E
- Q6 E3 K# d0 ?5 C, Z0 Y* p9 q代码展示
% P& |- e. W. u6 H$ b
4 R* a5 H# P, D$ Z, Eclass Solution {, _* A- L. T3 G
public int[] getAverages(int[] nums, int k) {; c+ `( Z4 G8 `7 C/ r
if (k == 0) {
8 _# T- K3 M }) E5 }! I8 q8 X return nums;
1 e3 P( B5 y) k! U, ^ }
- F% r P2 x' Y- h B long[] preSum = new long[nums.length];
; m: f' a; }* ?/ I3 Q, ?- ~! I preSum[0] = nums[0];1 w5 w2 U1 ^3 G; y, k- r; g
for (int i = 1; i < nums.length; i++) {' U. g9 @( x1 [
preSum[i] = preSum[i - 1] + nums[i];
7 {4 K$ `# r/ T' a0 I* W }
4 w1 _3 [' H5 x: n' g3 X int[] res = new int[nums.length];# i9 c3 z% R4 v a* k; i4 D
Arrays.fill(res, -1);+ r9 n6 O1 ~$ ]: f
for (int i = k; i + k < nums.length; i++) {
8 O$ r& q0 N3 \- U- V long sum = 0;
' \2 O* `! @8 v% r if (i - k == 0) {9 M2 U1 Y; i. v, w! o. T Q
sum = preSum[i + k];# t/ Q3 B1 L% R4 E5 T7 [2 P& {2 E
} else {% X; R) o7 k n( d% v! |
sum = preSum[i + k] - preSum[i - k - 1];1 K. A* X; x1 L, B
}
! [+ E7 i( x l! x L res[i] = (int) (sum / (long) (k * 2 + 1));
% ?# i- r% C; a' K }1 J. M% t+ J7 r% Y: f+ g; T
return res;2 @% C& L* f0 Y- X2 S2 ^
}
/ `) n, f6 U6 Y/ \9 K1 t$ U! \}
" L% Z5 ?; T8 V5 J( t% c$ v
/ t. |' V2 H, N【 NO.3 从数组中移除最大值和最小值】
; s9 N; H2 H* Z% A- i$ c
# ~$ i: b I8 F) K- G解题思路% g C1 M! x+ z/ W1 J+ K2 }
贪心,按照最小的花费移除即可。详见注释。8 ?' }6 s! [) X' `( m
& f* }9 A4 S$ I8 ^& C
代码展示: [7 J& I8 ^+ D$ f* ?$ `
' R5 B5 ]& o- ] p x7 lclass Solution {7 e9 z% T! ^3 U: R) h i
public int minimumDeletions(int[] nums) {, t8 H. t# y& R
if (nums.length <= 2) {
1 q) J5 k4 X% `/ W4 k8 ~2 N5 { return nums.length;( d$ q: `! _5 ?: q* g
}# C) G/ X; j6 i( `
// 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min' d5 M+ l' _8 d' `/ N
int min = 0, max = 0;
( f' C7 O2 a/ P3 `) B+ u3 b for (int i = 1; i < nums.length; i++) {' n- v9 X/ Q, [1 A. X0 ~
if (nums[i] < nums[min]) {' V4 X1 i$ K0 ~! E4 [. E9 T
min = i;
' ?; G1 E) S- v; k. Q) P" Z6 k4 P }
- l! ]" `) M& W8 p* H if (nums[i] > nums[max]) {+ G; s) x* U3 K* V
max = i;
7 d3 p2 R# d( ?8 D# I }
* M2 W S4 e: ~# | }& d8 Z3 q) A; s- v& U
// 要移除的元素下标为 max 和 min
; R8 a# D) T& G1 c3 T7 x @5 I // 此时我们只关心下标,谁是最大值谁是最小值不重要
1 L! T6 }+ a6 c* g* n5 U2 k // 为了方便处理,令 min 为较小的下标
9 x" Q- Y7 T" l8 I1 U if (min > max) {
3 g" t7 Q, p5 S7 a N4 |; V; D int t = min;6 H: v/ K; U( X- l& I _, c
min = max;
/ o& v+ B0 }) c& i5 n( |% m* S# y max = t;1 O+ b+ [6 W5 W6 z# G8 z7 d, E
}- f2 O* f5 t4 \5 o3 ?9 |& t
int res = 0;
' y8 @3 m7 B# \" `/ s& t int left = 0, right = nums.length - 1;
1 o, g7 D3 \4 ?7 i& [: x; i' i' X if (min - left + 1 < right - max + 1) {
# }- L3 {# n" f! s# S: q4 I res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
; ]5 e5 d m6 ~9 W. j left = min + 1;
9 w4 s; n5 C" }" X2 v res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
+ M1 f% @6 h) m: \/ i' N } else {
2 ~. @$ A3 U# Y res += right - max + 1;
: V# r- j3 [, M: B$ T9 V8 b; n7 K right = max - 1;% i C6 B0 W4 [* |8 Y( s& ]2 E& C
res += Math.min(min - left + 1, right - min + 1);
) R/ @1 w3 s2 O+ p; Q& G1 x! o; o. i% e2 U6 ~6 b4 G# X9 N
}
$ G1 O# H4 R. d9 Q) ?! k# v return res;
6 H- p9 G0 E& J) \! K. {! _! V }3 \: `5 H& G o+ [$ R
}
" ^( c3 b* @& n1 [8 w& U; Q8 S$ X8 D+ B8 [: I7 [, ?
【 NO.4 找出知晓秘密的所有专家】
|9 a5 x; i5 l3 h6 I
. p0 z( M8 {- i" q0 @解题思路
; w$ n9 A+ ?+ W并查集,详见注释。
9 D l+ s0 z* F" B( N' m/ h; E
: p+ r3 x, |' |6 a代码展示
6 d' d. Q: R2 P+ X
% j# g# {' r: R, o9 P+ U. h# kclass Solution {. ?+ g7 t9 F' W# v x/ O3 F" J4 P) Z8 R
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
: K4 K4 @4 s$ b4 N$ _ // 按照时间点将会议分组- O& p+ ~ ^( D/ P/ b% }
TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
+ J9 C( A( z$ D) d8 y6 j for (var m : meetings) {
+ U9 q7 l) v6 G5 a- |% S if (!orderedMeetings.containsKey(m[2])) {
6 r! ?- p2 s3 B$ k5 q5 |6 l; Z orderedMeetings.put(m[2], new ArrayList<>());
3 H5 P9 a, L* r; r$ C2 |4 M. v }
4 B0 G. F5 o5 {0 o6 C orderedMeetings.get(m[2]).add(m);
2 \) c% n! d5 V$ F, T }% C% v; o9 u2 X9 b! l
boolean[] known = new boolean[n];
H, F5 `+ d. J3 r5 e known[0] = known[firstPerson] = true;) y- l. W$ F6 N4 f
while (!orderedMeetings.isEmpty()) {
_/ p+ l( o+ @$ h // 按照时间顺序处理每一波会议0 b2 G1 O. |# `! D5 N5 [1 g" s
var entry = orderedMeetings.pollFirstEntry();
( V8 U" ^% T# @' ?6 O6 m var curMeetings = entry.getValue();' g; }# ?6 \! O% Y
// 使用并查集维护当前时间点发生的所有会议中,有关联的人( B: A7 L& j& n2 ~3 v9 `
UnionFind uf = new UnionFind(n);
& q" P# b" G5 F! j for (var m : curMeetings) {
' t0 v a( `( B' K uf.merge(m[0], m[1]);
' C" }8 N. T) Y& d1 O }
2 F5 o5 S# M9 \3 A // 枚举所有会议
* r: Q, R( V3 [4 E // 若会议参加人 m[0] 或 m[1] 知晓秘密
1 x% _$ t: {. e; }# s // 则把他们所在的根节点也标记为知晓秘密
2 F K$ T! F; w6 ? for (var m : curMeetings) {1 S/ y& @9 J7 ?5 k
if (known[m[0]] || known[m[1]]) {
3 W# s8 Y- Q7 ?2 k known[uf.find(m[0])] = true;$ F5 G2 g5 O% g$ p( d: F5 L! v" Y# \
known[uf.find(m[1])] = true;
7 q! t' g* L3 h! Z }
, R7 }- Y6 B8 s7 e8 B- b. b }
( U J3 Z2 G: A2 x, z+ D // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
% |1 {5 t) s+ T% ~5 r8 v% A for (var m : curMeetings) {0 [0 q4 [, i" B" M/ K9 K
if (known[uf.find(m[0])] || known[uf.find(m[1])]) {. P& [6 x% g6 Z6 f% R- W
known[m[0]] = true;' t0 H- ^1 d1 A# x
known[m[1]] = true; }' O' |1 T- _5 L7 C: k$ S
}
& v1 r2 ^. Y5 `& W& ]9 u, N( E }
- f4 Z. Q: o* ] }
3 t( @* V- V0 e: }( E List<Integer> res = new ArrayList<>();
% H1 I9 Z$ ^3 ~ for (int i = 0; i < n; i++) {
+ m' h5 p( } V" g" S5 _: D6 o if (known[i]) {! B7 e7 l0 r' L0 _* e n
res.add(i);
- \( y9 K0 u9 f- U }: L6 f) n% t6 w# ~/ b
}9 Q$ d l8 J+ p
return res;
# Z. ]( q" v' z9 l& S }
3 ^1 ]$ i! q5 ~% c* a2 Z; m}& Q4 |2 e0 Q( |) q4 W4 G3 R P( `
u) c* d% |; L* X! M; v0 t; j
class UnionFind {
* c p1 v6 {/ a5 @ public UnionFind(int size) {
* s- w0 y$ G u3 J) } f = new int[size];/ ~+ e( l8 ]8 Q A" S
Arrays.fill(f, -1);
0 ]8 m$ S! [6 Q }9 M+ X0 C' U# v' \
3 H7 R6 G) {/ {, [# P0 D: T% k: u' y
public int find(int x) {/ H. y: i( s. w! U: w- k* A7 N- @
if (f[x] < 0)
) h! g- C4 R( P" l0 Z1 r: v. y9 c! i return x;: b# _# U5 q0 d0 I- r. i R, b
return f[x] = find(f[x]);
% u* M$ i& i, f; k( Y2 ]) K0 x8 b }: P0 [! [9 \/ S; j
3 K/ |, y# g _) a2 p% E public boolean merge(int a, int b) {
# d* M q- {# `6 m# J1 N9 L int fa = find(a);
/ H) K. ?8 D7 W# U8 d3 U int fb = find(b);
1 y, l( ?7 E- o6 f: g if (fa == fb)8 n% _* h9 O9 d
return false;
6 \0 R) | Z$ g9 v" j5 f9 @4 X f[fa] = fb;" L2 J" U8 A V) }
return true;8 b" o% {% E1 ~* J$ C
}
6 }* F/ _7 n9 y& M/ G7 }
4 i5 d3 f, N2 o7 L public Map<Integer, List<Integer>> sets() {2 A9 j$ s! P* i! c. t' v' Z& O
Map<Integer, List<Integer>> res = new HashMap<>();
, ~% o: x0 E( }* K+ P for (int i = 0; i < f.length; i++) {: }$ \, v+ d" k2 R2 S4 D
int fi = find(i);
5 d( T2 p+ s: p# W ~4 K! o( U if (!res.containsKey(fi)) {1 ]6 t& Q# s3 p1 _$ r% i
res.put(fi, new ArrayList<>());8 ~; B. L( r* i) K
}
& E+ ~9 o4 U0 ]0 F! I res.get(fi).add(i);
& F, `' b7 `$ v# _. C: | }
. u' Q$ H2 F. S& ] l& ~ return res;
, Q% I, K" N% V3 `5 g }
$ ~: z0 f9 B% Q0 `0 K, n! z, ^/ o2 e1 E8 r; O8 N% u
private int[] f;
) ?: a3 B+ L4 V0 f3 T9 W2 j}& D6 c) V1 U: t, ?" q/ q' j$ h/ t
|