登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】
# |- V4 o# R3 }% @1 a2 M: S0 S解题思路
# i6 P. O& `" e& P3 l5 L签到题,循环判断即可。* q( U% B- J4 \% k5 t6 F
7 \/ r* r+ w0 ?( O( r
代码展示# f/ B# \8 S2 B6 A
3 b9 E# _; [* w0 y' i) _) Fclass Solution {
4 }3 w0 X; h5 ^# r0 J* [ public List<Integer> targetIndices(int[] nums, int target) {
0 u0 I9 m3 m% w5 e- p$ Y Arrays.sort(nums);
1 {& f8 L Z: H" b/ K6 n$ o8 H: I List<Integer> res = new ArrayList<>();
7 s" Z! J# z+ X- \) Y for (int i = 0; i < nums.length; i++) {
. W/ s- f. g& `$ f if (nums[i] == target) {
3 q0 K4 A( V/ T& b/ c) V2 Q6 O- T3 B' r res.add(i);
& x7 |0 s7 u5 R% Z, C }& @3 V' q t0 b# \5 i: i
}3 z8 g$ m0 W" b7 a3 u) o2 Y( `6 n
return res;
% ~4 _5 U. L1 O. z }2 O3 G7 M" R! [
}
+ R5 y$ a9 f! f# y* r
2 z- B7 ^2 N, m& I5 g: ]【 NO.2 半径为 k 的子数组平均值】
4 [- K: V2 n$ r! [! r解题思路
; }8 o/ J2 z& [5 o! H使用前缀和计算区间和。注意使用 long 类型以避免溢出。7 u2 D/ U4 z1 A, O& S1 [3 f
3 u* B6 e$ N( x$ v/ J代码展示
' D% k* ?, ?9 v K1 A, k& O' E1 z8 m' w" l
class Solution {
6 F1 M. y! d# a- m/ ~+ C public int[] getAverages(int[] nums, int k) {
. o2 T) Q3 _1 E. F; `, ^ if (k == 0) {% M- Z8 O2 S9 ^4 R0 L) z
return nums;
8 U5 x: f. [/ C4 p( X }
8 V: x: Z" i3 h9 d long[] preSum = new long[nums.length];7 K3 H, {* b" g9 l% ?: v/ F
preSum[0] = nums[0];
1 `. b9 O( o& P6 t. R0 Q: l0 j for (int i = 1; i < nums.length; i++) {
7 L+ V* J4 y! w9 D% U. D preSum[i] = preSum[i - 1] + nums[i];- j* }. \) V* |
}
- T' T/ v2 t& E int[] res = new int[nums.length];
( r, F V+ p8 D0 Q [5 m# ^3 _ Arrays.fill(res, -1);
^) |: D x4 S! i for (int i = k; i + k < nums.length; i++) {
5 M# o' @, K' g3 {9 P2 c/ ~. o' r# z7 x long sum = 0;
: B5 g7 ~. q% O4 } if (i - k == 0) {5 x0 j9 C0 ?/ V$ }* x
sum = preSum[i + k];
* ?6 B: m- A+ E" i$ Q2 ^2 k8 y' f( R } else {3 V2 f7 X# o6 ?: v. p7 A
sum = preSum[i + k] - preSum[i - k - 1];
* v. `* V. L; {9 Z$ Q1 M$ v }4 V) }3 J5 n5 n
res[i] = (int) (sum / (long) (k * 2 + 1));! C% x5 r: h9 w- n% o# i
}+ U4 b: w/ g/ R! l& w0 S2 u7 m
return res;4 W6 ^ ]6 @3 n- e4 w" K1 B
}% R2 x) X S1 f$ T: u1 K1 V* A
}; w a8 p" y& K' ], |: T7 j
5 O, S& p/ z7 u: b
【 NO.3 从数组中移除最大值和最小值】
& ?( {" I* d' b
. x4 ?* x$ A# H/ ~0 f解题思路
" Y, d3 }6 C3 C+ Z' E# P贪心,按照最小的花费移除即可。详见注释。9 z% L8 F, }/ l* y a$ b6 B5 W% p% `
. W$ l+ j" T% p9 {) T( x7 W代码展示
7 O% {0 W. @; a# ? R& J
. L: t0 B0 X' qclass Solution {
8 n+ X T% N. d: o4 G" i; m9 J8 B public int minimumDeletions(int[] nums) {
5 x9 O+ ?( P3 s# | if (nums.length <= 2) {4 b+ E! t9 ]6 }$ U
return nums.length;) \4 Q8 A; K, N5 v- ^
}
( x0 c6 d8 K; B // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
! S5 |, Y+ Q6 `6 q4 ^' ^ int min = 0, max = 0;: J3 H9 L2 O. G) p
for (int i = 1; i < nums.length; i++) {* n" s' D; |& y5 e1 H; {
if (nums[i] < nums[min]) {
: ? h$ J5 @# z) C* e9 X9 V min = i;) T w) J$ d `4 I' u: \# q7 |
}
5 |0 X2 l% r; M4 F* l/ h if (nums[i] > nums[max]) {
( k! I; M# A1 Z U3 c) u8 K1 r/ [ max = i;' M0 f# H; m5 e7 I/ R8 n
}% x7 F3 z' {. {" q$ V# z% x
}; g; n! v, c( S7 H
// 要移除的元素下标为 max 和 min! N! X1 T/ k7 i+ K& z% E9 b/ X: _
// 此时我们只关心下标,谁是最大值谁是最小值不重要5 s9 M% P8 e5 k
// 为了方便处理,令 min 为较小的下标/ j( q) T# K- b* M; l
if (min > max) {( [4 T0 d4 T# Z5 }# W9 Z
int t = min;
) J( S7 D# d9 \% \# j5 [ min = max;* C+ _/ ]# c3 M/ P- ?- O2 \; k! I& W$ R
max = t;
# S: ?8 ]# Z0 x }
; T. C n4 M& d8 l. \ int res = 0;0 f' z/ ^+ K0 S% L
int left = 0, right = nums.length - 1;* [) Q% d' R, i+ @
if (min - left + 1 < right - max + 1) {
1 {* `9 f' ?% ^/ z2 [0 I* O res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min/ L/ S; a( D; q5 J& l
left = min + 1;! {) {; ^4 g6 P* b8 H
res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max0 U6 H$ \- X% D# n! ]* b8 X: }
} else {6 ~2 o- i3 Z6 }! Y' c& B* n) q
res += right - max + 1;
. \, q0 F2 t8 j- Y% P right = max - 1;
! d! R2 Q5 u! h" v: v; w5 Q- g res += Math.min(min - left + 1, right - min + 1);- A% H$ E; L5 p4 [
+ P( {: y5 l- c1 E8 m8 q
}3 c: C' V& h* [: t7 M2 z9 e
return res;
& W& |5 G1 {1 a6 Q" w0 `* C }
0 U+ u1 y, u. E}, D, u5 K7 J. W/ n# I0 N, G
0 R8 @7 H4 p) x$ y5 o
【 NO.4 找出知晓秘密的所有专家】: I3 S# {- _, D6 y7 T$ Z
2 q+ ?! a* I* B& r4 k解题思路* V3 _. K' b- Y) u
并查集,详见注释。+ F$ F+ d- M- x" Y, |
6 k$ C& B! ~- W: K
代码展示# f! }2 e* h6 u0 U; U3 G
, J: G% q: T4 Z) c) [ k6 ^$ t
class Solution {+ Q& q) C: v% O7 M7 `
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
( F. t2 g0 m/ M2 i. [) r' }: n. M // 按照时间点将会议分组
2 z& B' P. [, V TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();! X5 ]8 I: @# ]2 _( Q
for (var m : meetings) {
z5 E3 @# @" s/ L if (!orderedMeetings.containsKey(m[2])) {! ` E& {' d* H f' |- T" D2 U% ~5 I
orderedMeetings.put(m[2], new ArrayList<>());
3 I; S2 R' q; E$ b }
3 {+ C4 _" X7 G# t0 ~/ D( ? orderedMeetings.get(m[2]).add(m);
6 Y# V$ @6 n& L8 z) P$ Z6 U; g }# {/ u* y& A6 g8 e+ H( Y3 g6 C
boolean[] known = new boolean[n];% T+ |$ ?+ a* E
known[0] = known[firstPerson] = true;1 y* B! }8 G% d; f: [3 X
while (!orderedMeetings.isEmpty()) {
# x1 V; D9 i3 h0 C! K- e // 按照时间顺序处理每一波会议
8 u# x; l! x" U7 q( M% J U* _ var entry = orderedMeetings.pollFirstEntry();. s! b' F5 z* R' V3 f# Y6 a
var curMeetings = entry.getValue();
3 i9 r6 c5 s3 m* ?# z/ T0 } // 使用并查集维护当前时间点发生的所有会议中,有关联的人
^% ^ q* J: i2 D UnionFind uf = new UnionFind(n);9 Y; F$ G( f$ ~; L! V/ \, I! U
for (var m : curMeetings) {/ i7 T1 I1 C4 O& g2 N
uf.merge(m[0], m[1]);
+ d$ o; ]* g8 G2 x }
' z, O# W8 z% y/ ]3 e* b // 枚举所有会议+ _" k/ Q5 B3 w: B7 x
// 若会议参加人 m[0] 或 m[1] 知晓秘密1 p7 T& W/ n8 y$ A7 F
// 则把他们所在的根节点也标记为知晓秘密" ^/ R: q$ O i1 x! @! F1 ~
for (var m : curMeetings) {
6 c, U) N7 D. `: E6 R if (known[m[0]] || known[m[1]]) {3 A1 f# ?- ?# _! p! W% F Q' v' m
known[uf.find(m[0])] = true;1 U L0 n; Z4 i3 r0 |# {: H
known[uf.find(m[1])] = true;
3 E; j* H8 B* C0 s) q }; D) P3 }9 Z/ m+ k# E
}
+ I& M8 i# `% V1 s // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
2 n& F3 h- B: w; d2 v for (var m : curMeetings) {
( _ ^$ D6 W" G) i0 t if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
- x! \, h% K4 ]* m2 p known[m[0]] = true;
6 z5 w Y ?$ k known[m[1]] = true;
# ?, d2 J$ _# T9 Y0 u }
, ~; c i5 {2 k# ]4 g/ s# O }: n: |9 T' i% r# L: m
}
4 ] z; f: C' V% k4 ~ List<Integer> res = new ArrayList<>();
) a0 w* h6 V+ i( {, C for (int i = 0; i < n; i++) {. A. Y0 @1 T- \2 f8 Q/ t
if (known[i]) {
1 ]9 {% |: Z4 g; z0 h( T4 P res.add(i);1 }7 `8 i+ r4 H8 a' e
}
( g' b! v/ L- ^$ H# q& B }2 p/ ]; ]$ ~5 l K0 J
return res;. @7 o/ J- P, F t6 S
}
' b2 e* k% S, v8 q$ S}3 p1 d1 H- o+ y6 |$ [ X
2 {( [; K# U1 d g5 e& z. W' p
class UnionFind {
( H) J& ?5 o# P$ t public UnionFind(int size) {1 T- \5 y% H8 q% N6 o
f = new int[size];5 S0 P0 s. e8 j1 s& Y& p% R6 K/ d
Arrays.fill(f, -1);
, i2 A# b7 @0 j3 e' O( A }
$ E$ e9 l# Q/ Q& P
( D# @( v/ Q% i% Q7 G4 E/ n: a public int find(int x) {
' b- O+ ]! { h" i) H8 V if (f[x] < 0)
' v$ s6 K& a0 L* Z return x;
2 A" N3 W) A; y3 o return f[x] = find(f[x]);
1 P1 b2 N4 g# f: L2 S }( e0 G% d, d; V7 P# M
/ H: n5 A% ^$ X; P9 H public boolean merge(int a, int b) {
" a6 x5 U" B+ ^' o8 G- C int fa = find(a);
1 n# G# C. c; r1 B6 Z0 E int fb = find(b);
' G5 I* v2 `# N# \1 V& v4 e if (fa == fb), \4 ^0 L2 j( B. v$ l
return false;
9 K& v' m$ A. r' o7 d4 n# P3 L f[fa] = fb;# R% P, d7 ? @3 h+ Z
return true;( N! ?" _6 Q- \ t
}
2 B7 H# j+ v! P0 ]4 f. ?" f2 b5 ]+ Z4 d
public Map<Integer, List<Integer>> sets() {, D1 @4 ^2 l1 K$ e ^ A; w
Map<Integer, List<Integer>> res = new HashMap<>();
* E6 ^1 B7 [+ X for (int i = 0; i < f.length; i++) {
?) g2 I4 V n int fi = find(i);1 b4 M, J9 W" w. y$ h; E
if (!res.containsKey(fi)) {8 p3 h% k. F" x- h; Y+ l
res.put(fi, new ArrayList<>());
1 w, }8 c8 W! ~5 w! z }
8 D A) `, E% n! @& m4 k: P d res.get(fi).add(i);% Z7 y5 g s, Z8 z& V8 }2 \
}2 T& y8 i- a) T5 |
return res;. b1 Y0 [) \* Y( P
}
7 ?0 B; m( h; t
1 L% i4 }' [1 v) r- f4 K6 }' y% w private int[] f;
# c/ o1 q. [1 w7 F4 Q}
1 p7 k0 w; l8 m/ b/ |# U: @; q |