登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】% B/ V8 g v; t8 O0 S6 b
解题思路
: d6 ^& h( i2 u" [( g) K- M* U签到题,循环判断即可。* z& s8 K$ T# P! t- O
7 p- w1 `6 E* e4 ~. p7 r0 g @代码展示
: H3 x. w, U0 H7 O
" ^! _3 _; X8 w- uclass Solution {% o2 ]/ Y: g- K+ \" E
public List<Integer> targetIndices(int[] nums, int target) { E0 u: ]4 K/ n9 I# W
Arrays.sort(nums);6 n% q9 V2 N) X1 A2 l+ L/ `+ {3 a2 g* f
List<Integer> res = new ArrayList<>();2 |/ O, Z Q0 a/ z; ~1 ^1 D' Z D
for (int i = 0; i < nums.length; i++) {
7 r* U- G* C: P9 j. `1 T if (nums[i] == target) {$ I; [7 ~2 P7 z
res.add(i);
; i" ] h* {( A3 ?# M }( A: M6 A9 B9 M! ~6 v( ]
}& J6 S$ B1 \* L( S' ^) }! T
return res;/ z3 [2 J3 z" Z: a
}! o; S. o- x, N; S3 F& E
}* ?+ t# z7 c- I" v J3 v- r M
$ u. C1 e( Z- d: X【 NO.2 半径为 k 的子数组平均值】
$ j4 `/ W1 }* X( v. u解题思路
# l- h5 Y' H6 N使用前缀和计算区间和。注意使用 long 类型以避免溢出。/ L4 Y F/ m- f4 Z. T$ P+ w
) k+ Y$ }% G$ S ]: n2 ]
代码展示, m/ c2 J. B4 D8 \& d Z' r' e
0 c0 I! C2 r+ s& I5 {class Solution {
2 h8 O0 `- w! Q9 P! h public int[] getAverages(int[] nums, int k) {+ N# y, H# |- C& L# Y. M8 n( p
if (k == 0) {5 @% ^! r5 U3 n" b: ~
return nums;
. B3 R C* i( z5 k7 ^ }
. W; | }; q5 M long[] preSum = new long[nums.length];4 |6 p# O* b2 ~5 [5 L. @& ]
preSum[0] = nums[0];
( t4 \$ k* K. T7 Q1 r) C for (int i = 1; i < nums.length; i++) {
* k5 D( \7 G& S1 p+ u preSum[i] = preSum[i - 1] + nums[i];! n: ]! K$ p3 ^' N) J# A: U
}
+ c+ X1 b! G* j: m int[] res = new int[nums.length];
( p- X4 q" O+ O9 `0 X/ b Arrays.fill(res, -1);
7 d7 j2 w3 I O4 L: b K for (int i = k; i + k < nums.length; i++) {
# F' s' l% N. [# s3 \- k, T- |* s long sum = 0;
. [3 b- p2 F7 k" J, a+ [ if (i - k == 0) {) g# k9 N' c0 a+ P. ?2 ]4 u# ]
sum = preSum[i + k];& F1 d/ O8 I% E& p. p Y$ z* \' z
} else {
' l5 m" T4 M- p sum = preSum[i + k] - preSum[i - k - 1];% i0 T t1 l# o, B0 ]. `
}
+ N: R* s$ _3 r/ `' X; }9 R res[i] = (int) (sum / (long) (k * 2 + 1));% Y$ m$ y7 y5 E. s; V5 y
}* M1 S$ y+ q! _
return res;: y0 |: B% C, ]1 N Z6 g
}/ c1 M6 E" _$ ~- d2 }
}$ u5 L0 U$ B* L2 U1 |+ |. G
$ M' H9 d- Z: l
【 NO.3 从数组中移除最大值和最小值】: w) u, ^6 l H. ?- X% A4 }$ Z( r
$ p4 {0 C% ?# R+ k* o解题思路
% P5 a: r4 C# _: p8 ?# p贪心,按照最小的花费移除即可。详见注释。
% ?* p' S8 a! Y) ~ G
7 W9 T7 o- y% F6 s3 x* p代码展示6 ]' z8 l( h8 t. F# p
! T" N" \5 t% z0 O- b. fclass Solution {
. P" K8 W$ l) T7 V1 t, A6 V4 { public int minimumDeletions(int[] nums) {3 U8 ]5 e- j; r1 f& j9 e7 s% f
if (nums.length <= 2) {7 ?. `; e6 Z O) j
return nums.length;8 s5 \! j. y8 j2 O" U1 z
}
" \+ k+ Q' c4 O: N: K // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min" p* w# D9 j0 R! N& M2 x
int min = 0, max = 0;. |0 a# R: F. T4 S6 m q: P& H
for (int i = 1; i < nums.length; i++) {
o p. h5 y) y. T8 Y1 Z% \ if (nums[i] < nums[min]) {
0 V$ y5 [$ b% b7 t min = i;4 n2 d: n) a/ S& g. D5 O
}: f9 V6 l- d) e, F
if (nums[i] > nums[max]) {
6 @& c# n ^/ d$ l- o! B0 L" e max = i;0 ^4 E' X+ v. o' N7 Y! ~, L
}6 x% w& ~5 h! l7 \4 s# X
}: G( e9 u1 j" Y' q
// 要移除的元素下标为 max 和 min
3 t% g5 `4 K$ k) U; c. G. S // 此时我们只关心下标,谁是最大值谁是最小值不重要
+ _& v9 G" H. Y3 i" m2 } // 为了方便处理,令 min 为较小的下标
* d6 v/ _. p% D/ } if (min > max) {# M3 V- U; B& a% k6 l. _' f8 Z' n
int t = min;- Z6 F8 k9 u; U& m/ {! b
min = max;
- F+ l/ ~; N! n& s* G! B max = t;. r2 H2 |' [* w! `6 O" ^3 F# `
}
" z) |; E+ ~5 l, @8 W- q3 e+ A int res = 0;; w% c# ^3 L6 w' G/ R
int left = 0, right = nums.length - 1;
( B1 g2 H7 }1 G4 [! g* c3 r if (min - left + 1 < right - max + 1) {
8 d! s8 w# Q4 b( |) U res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
/ w' g; J& g8 e* @1 n# \ C8 z9 Z2 z left = min + 1;! n V7 A8 V3 S6 f; X$ H
res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max7 z% C, F3 C+ {( W$ O
} else {& x5 x/ m3 b. B; j
res += right - max + 1;" n6 W, q% f3 R& Y5 n/ x
right = max - 1;
4 L8 z3 A/ {7 c4 T res += Math.min(min - left + 1, right - min + 1);
( w- s& F: w, e( A f# n: p* y1 V+ d
! [8 l. }+ ] p }" e; p* H# ?- `7 I3 ?3 V3 F
return res;
! n/ j' c7 }& l6 c, k/ p/ K }1 V8 P2 m/ e" Y: O: k4 j
}
" q' H. r6 a4 Q5 d. Z# r! ^7 R1 R1 \6 R. J6 N- ]
【 NO.4 找出知晓秘密的所有专家】
+ n% r* M; c7 p( U8 ]( Q
& f) \( D. @! k6 R4 |: c解题思路
) D( J& b9 m$ x# h并查集,详见注释。" ~; X3 ^: G$ H
) S( G8 \) z. P1 A" S. S. {
代码展示- p# _& I/ g! q5 o% q" P% u0 o
6 x! t$ z3 }" q* T' ^class Solution {
" I; E! J& M3 k2 ^ g v( F) s8 | public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
1 ~* y* Z0 x4 V' S% {! | // 按照时间点将会议分组
! Z& a; Q5 p9 l( F, O m6 } TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>(); F# G& B( L: [: A5 D" \
for (var m : meetings) {& J+ m( O' C9 C5 B+ ~$ e
if (!orderedMeetings.containsKey(m[2])) {; s9 @* U. Q& E6 g n4 o* K
orderedMeetings.put(m[2], new ArrayList<>());
3 @6 u5 a: j% m }$ }0 \% v" w& k8 i; f
orderedMeetings.get(m[2]).add(m);% J7 }. h8 X: B' k0 P
}% s; u7 {3 ?* d- O
boolean[] known = new boolean[n];
2 B+ h. r% ~" f' |( X: ~0 Q+ P known[0] = known[firstPerson] = true;( [8 d$ c% V3 y5 K. t. M0 E' m. L2 b
while (!orderedMeetings.isEmpty()) {
0 h. R+ X# i4 p1 r' F4 i5 U // 按照时间顺序处理每一波会议
& E; o* F$ s& _ var entry = orderedMeetings.pollFirstEntry();* ]0 l. s! r; K+ |7 j
var curMeetings = entry.getValue();
4 D5 Q8 c- F7 V8 s& h- t% Y' g' T // 使用并查集维护当前时间点发生的所有会议中,有关联的人! U% r* T" ?; N6 K
UnionFind uf = new UnionFind(n);" @! H9 b" Z) c. A. c; j$ P
for (var m : curMeetings) {8 E+ |# s% q+ L, B
uf.merge(m[0], m[1]);
% F7 i; r. w$ R" d: Z2 I }$ S& B* A! i, m# l: n( V$ W8 z1 X/ p
// 枚举所有会议5 i+ E% q: Z! u" d# i h& w
// 若会议参加人 m[0] 或 m[1] 知晓秘密
" F" z. n& n* ~6 o$ A // 则把他们所在的根节点也标记为知晓秘密
# t/ |7 v! J/ x1 C4 v! V' D for (var m : curMeetings) {4 p! a" u. n: ~& `1 \5 N
if (known[m[0]] || known[m[1]]) {+ M! g. Q3 N, {6 L1 s/ D+ V7 {
known[uf.find(m[0])] = true;6 v* r" p/ \, o+ U) U
known[uf.find(m[1])] = true;7 [# t( _" q0 Z$ w* n
}, k$ o4 A" j- X( }
}
6 Z# f; C5 X# W5 k // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
, }; }. P. I: U, E8 z& T2 A7 y4 n for (var m : curMeetings) {
% A( I5 ?* ^4 z& I if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
5 z7 R1 D* p* I9 }& w3 \- g% [3 E known[m[0]] = true;
# J9 q( H" I2 K. v8 u known[m[1]] = true;, ]( z+ A' ?7 A- Y2 C3 e: q
}' w. O- j, i9 h% [# B
}/ A5 m/ Y; Q9 C& N W c. X
}1 X' W. g0 Q" k6 F! N
List<Integer> res = new ArrayList<>();7 R! W4 w6 _* f# H4 r$ p6 P# v
for (int i = 0; i < n; i++) {+ Q- K$ L$ ~. n5 K* @
if (known[i]) {: C+ a7 M6 `* S% B+ ?) p) L
res.add(i);& v* s' A$ J* h! z. d/ n, f
}
' Q6 j4 k$ k; q$ r; D4 N: V } K- E \8 q. R
return res;" j$ `5 h( }' `, a( y( I! ~
}
/ E5 y, C( M. m& C0 c}
4 o2 k3 S' N! [, s% B0 ?1 V" N0 k+ u5 X6 W# n. _/ M
class UnionFind {* r( N- v8 t z- h7 e
public UnionFind(int size) {
F/ H; R7 x" ^ f = new int[size];
4 B+ b' V6 P* L& Q4 s7 K5 U Arrays.fill(f, -1);; t* N) n: w! {, M, G
}
, J: H( Y/ e9 D5 }& _' r/ K1 X d; u- q
public int find(int x) {
- _4 g3 x& E( ^ if (f[x] < 0)
1 X* T! W3 v$ \5 \9 M return x;4 O0 v8 b- \* [6 v% j& ]
return f[x] = find(f[x]);
! l; l1 } X" R7 _ z K( V }
: E# X- e: y/ D5 m& F8 S6 L6 o5 m3 U
public boolean merge(int a, int b) {7 Z0 B/ k8 D* o3 y( j, \8 \0 `
int fa = find(a);4 c2 |# k: E0 ]) I1 f3 K
int fb = find(b);
2 R( z7 @$ I% C if (fa == fb)! m- m q" @: D" M. @
return false;
7 d, t, V# f) q% u' u f[fa] = fb;# i9 E8 x- O2 x
return true;
4 @6 D( F& N3 g3 ^: X# G, Q }
3 i4 K+ m' q% Q' R
1 ]) ?! b' X. V$ \ public Map<Integer, List<Integer>> sets() {
/ ]- F ?. [' N Map<Integer, List<Integer>> res = new HashMap<>();& V/ b! K! a& }
for (int i = 0; i < f.length; i++) {
% [+ l& A0 \- y: ~ Y# w int fi = find(i);
V7 Z) R, X+ [1 ?, J if (!res.containsKey(fi)) {
& B+ {3 O3 ]; N1 K& z& [& ~ res.put(fi, new ArrayList<>());% X% q9 G# w7 `0 N9 E8 B% t- l
}% u. z9 [2 R/ x0 h9 j+ i; a+ K
res.get(fi).add(i);
6 L. Q- n' |' z! L }0 k; h6 w) C( Q- r! I' @0 n1 U4 U
return res;
+ }% q* }2 T/ q3 B) N }
& i2 x8 H. c% _# S$ {: o
1 n6 }; l) _- b# X# y0 z private int[] f;
. h* D1 D/ t' a4 ^/ o' U6 H8 K}1 k+ V3 }; y' ]! p5 R( r$ G$ Y
|