登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】
1 p+ c* B4 T W$ z解题思路7 ~+ ?9 j, L) v
签到题,循环判断即可。
" o. W: i3 o! _" P2 q$ M9 G0 a+ Q9 K2 M0 V& S
代码展示
* M* P+ j- w1 a5 C
% b3 K b* i# O3 ]class Solution {
! v% V( n3 x+ ^5 J! _2 a public List<Integer> targetIndices(int[] nums, int target) {
1 a" `# w9 z& e5 W2 K Arrays.sort(nums);3 o. Q! {) U! a' ]3 d
List<Integer> res = new ArrayList<>();
# E) ^& ?* x$ I for (int i = 0; i < nums.length; i++) {" F9 `; v9 U( W5 A5 e6 b
if (nums[i] == target) {" `5 E# E7 v2 x; W! K& ]# u, E
res.add(i);% z6 [1 X9 A0 W( V4 H
}2 V. F) d. W3 o7 q
}7 t! t4 G" t" D" I
return res;
" g o. z( G2 `5 d E3 a; e }
0 _8 K! {; W0 C/ ?( N Q3 M}4 y2 w2 J, W6 |. Y' k
1 |3 T' j% o: K9 `1 i【 NO.2 半径为 k 的子数组平均值】
3 n* Y3 S* U& l9 U4 I解题思路
5 {" J3 b+ R9 Q2 S+ M使用前缀和计算区间和。注意使用 long 类型以避免溢出。
/ J) X/ m* X3 e8 c% D2 k1 `) _3 V6 y: x4 g% D
代码展示. f$ ?# |4 I2 C, P
; ?- w- W; D; xclass Solution {
2 [* {1 }: Y+ E, M& V; P) V5 w4 X( H public int[] getAverages(int[] nums, int k) {
; f$ b3 I3 ^& [; H3 i* Z if (k == 0) {
' G: J: l; o" U# a return nums;
, f% W* e+ U Z3 j5 ~% T: y2 E }
0 [! x A* z, g/ S$ h long[] preSum = new long[nums.length];
3 e8 x" a% {: i3 z! i preSum[0] = nums[0];; |" h; W s: [8 ~" p) H( a
for (int i = 1; i < nums.length; i++) {) ? K0 n0 w3 j5 e: K2 _
preSum[i] = preSum[i - 1] + nums[i];3 y8 f: H( }( D: q5 X
}
1 G$ s3 W/ ^2 K- b int[] res = new int[nums.length];
+ Q" S2 q6 F- M0 g. W Arrays.fill(res, -1);3 R& X6 {) Z3 o- r1 D
for (int i = k; i + k < nums.length; i++) {; C' A$ t9 w, Q" F9 v! n
long sum = 0;! e; x% H8 }8 k! E/ O$ U. `; G
if (i - k == 0) {
8 X8 k- s/ S. v6 [6 H' ~/ y, v5 C sum = preSum[i + k];
; g N0 n6 R# f' z+ p( i0 x } else {
: p) ]! R3 @; I( N% o9 T1 T sum = preSum[i + k] - preSum[i - k - 1];
, [& t4 I7 k% Q. y/ a }
+ c) K+ N6 n3 z1 }6 I+ z/ g% g res[i] = (int) (sum / (long) (k * 2 + 1));
`' |/ d9 b& O7 e0 r6 K3 c }5 U N B( c2 Z+ g* ~3 V. d! \# h
return res;3 r- w9 x/ M2 d2 ~4 s. K
}! M# f8 M; D) @$ g$ B$ N: u# o
}: w) S2 D. J' m, Z1 z- y! e
, A0 ]7 ^! B' ^; ^9 j: C- P6 _【 NO.3 从数组中移除最大值和最小值】
4 N3 b7 z. Y; O% H9 \# f7 z
" u+ y* K0 S) D3 J; `解题思路; J6 V( F$ t/ w: f: u
贪心,按照最小的花费移除即可。详见注释。& s5 V, X) Q- S- Z1 k
* {7 { W! o5 m& ]7 i& f代码展示7 o. P8 H$ ^/ R2 @1 d+ V
! `5 W! y6 C; w" i
class Solution {' i& g+ q1 `7 p+ o- N7 `+ N) W/ ]
public int minimumDeletions(int[] nums) {* ?' A8 a: s" I2 I
if (nums.length <= 2) {& ~, ^- n' }# n& b6 \7 j
return nums.length;- M/ a7 I, M" T, z* N/ R7 L& P, ~( S
}
& r& ^. X* f j6 Y // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min4 S4 y/ u+ `# i" S/ Y3 \9 H) `! [0 [/ g
int min = 0, max = 0;- ^ d q4 y! l) w; p
for (int i = 1; i < nums.length; i++) {
4 S C R/ {; m) w: V3 b4 j$ X) w; a if (nums[i] < nums[min]) {
+ ]. w9 X: K) {! w5 ] min = i;
% V1 h: }6 P2 T; _' F2 _ l& x& i4 A9 H }
; r. w) M1 L. u7 D if (nums[i] > nums[max]) {
2 a$ X8 d8 r0 U! c) Y max = i;
) ^5 G- V, Z; ?5 o( S1 Y- ?9 C }' r$ t& h) ^/ l
}# I4 F. A( q" _0 L. Z* j$ I
// 要移除的元素下标为 max 和 min
% \$ o9 D' z% \' p* x' j' _( O/ V! r // 此时我们只关心下标,谁是最大值谁是最小值不重要
) u# T, r2 U/ ~5 q, O9 R // 为了方便处理,令 min 为较小的下标$ N4 b: S9 i$ x: Q
if (min > max) {( C% s$ d% ]! b
int t = min;
/ V1 ~. P- }1 R. H( | min = max;1 @* m& H# I$ n; M0 G* Z& ]& e4 q
max = t;
. f: r% l. h* e0 p& ^3 M }2 S6 J7 x: x3 S
int res = 0;
2 `6 Z8 H% W- ], U7 n int left = 0, right = nums.length - 1;
' V- _, i" N" { j, H& q if (min - left + 1 < right - max + 1) {
* M& k/ s2 [. B: y+ F res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
# V+ U: D* L, y+ Z/ X5 i8 T left = min + 1;
* _4 } H$ M5 q! {3 u res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max. k& G8 {& @$ K1 ]% g
} else {
6 T# n$ m& b( A, T! j res += right - max + 1;$ E: h, C3 I; @ v1 \. |1 O$ ~
right = max - 1;3 X! \( |, i! \- O5 _) `- P4 Q
res += Math.min(min - left + 1, right - min + 1);
$ L' ~( A- ^: L( y7 `% ]8 p9 o% }0 M- N# [
}( T3 ^$ T) f) l% u1 X! X9 _
return res;
+ ?# w9 I0 n8 D' z8 _6 e }
8 U( H7 c+ X% |0 N}
5 K6 U* N2 `( { O7 ~6 x/ n% i H2 `: q" k: J
【 NO.4 找出知晓秘密的所有专家】$ O! Z" Q t! m* ]1 o
3 _+ P6 `7 f# U4 ^7 D解题思路; E N/ `3 s( k8 M/ V; T) b
并查集,详见注释。: H/ \2 P" O: b& T
6 O2 m! r/ r9 Y+ D代码展示
! ?$ c, ^# d% A6 n- D4 b) }3 G7 I: L7 T, U L4 Z0 I
class Solution {
/ S% Y) P3 g! k( b0 ^& R- [ public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {) a& z! e4 _' d0 E2 E2 b
// 按照时间点将会议分组
1 N4 S; J( S1 S! W TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
- b" [* x- t1 }% K1 [6 G5 i U for (var m : meetings) {6 T5 K p/ B* V( Z; u2 E2 V5 m+ a2 i
if (!orderedMeetings.containsKey(m[2])) {
# o/ @: h% s: D( Y8 \7 h orderedMeetings.put(m[2], new ArrayList<>());" w8 P. T+ S9 J4 a z' b
}) y( F! |5 M( a3 H
orderedMeetings.get(m[2]).add(m);
" z) T# u9 a; a+ G& j a& i }
( \0 a6 V0 l8 K5 O1 B5 l9 ]4 P boolean[] known = new boolean[n];! }* l4 h; j; Q: _$ @; E) |& C
known[0] = known[firstPerson] = true;
7 T% c8 G5 S( x" j0 a while (!orderedMeetings.isEmpty()) {# p& H8 y7 A3 Q
// 按照时间顺序处理每一波会议: x( V; `7 X0 m. v2 F0 [7 L
var entry = orderedMeetings.pollFirstEntry();
, j/ P' w J1 k" x& A6 d var curMeetings = entry.getValue();3 A9 c8 F0 e' S
// 使用并查集维护当前时间点发生的所有会议中,有关联的人
1 c8 z% n' L# \) R7 ^. p( R ` UnionFind uf = new UnionFind(n);; P* R" n3 h" L7 w% n: c' `" x: D
for (var m : curMeetings) {
: r$ ^$ c8 F% c& W uf.merge(m[0], m[1]);
/ ^5 D, }( l' s4 i# \. L/ h }
, X. `: H6 l* X$ q // 枚举所有会议" K- q# B' e' J* F7 V6 _
// 若会议参加人 m[0] 或 m[1] 知晓秘密
+ I- ]8 K# a1 D& g R // 则把他们所在的根节点也标记为知晓秘密
# Z* G- e; Y6 O5 R for (var m : curMeetings) {
" v/ B6 P6 D* S9 t if (known[m[0]] || known[m[1]]) {) k' c6 n$ ~0 l
known[uf.find(m[0])] = true;. a* D) J) Z, H1 _
known[uf.find(m[1])] = true;
# g: H7 g8 J0 \& `4 C2 P } C" ?' z! b) t8 z
}% G9 q* h) h n# {6 |6 f* p8 j
// 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
0 o' Q# {' G( y$ T2 w7 F/ F for (var m : curMeetings) {
* H* k+ s, G7 q" q if (known[uf.find(m[0])] || known[uf.find(m[1])]) {5 b! R5 H3 R E. p1 h" e9 `$ M
known[m[0]] = true;. n6 z8 X0 Z5 U1 W1 p/ X0 P
known[m[1]] = true;6 F% H! q" x% f. j& {8 {* d- h$ R/ H& j
}
% S. z8 t+ b0 F4 k) P1 X }: x5 a! l4 h7 v7 X2 \5 e
}
& C n9 M% [" s$ o; ^: u8 ` List<Integer> res = new ArrayList<>();7 P: t' E, Y6 p1 w5 S G9 }
for (int i = 0; i < n; i++) {
7 p/ i# j. m. o& {$ o7 k if (known[i]) {
' z5 O' {4 G* P) f/ W* V res.add(i);
* f8 _* t1 Y# [8 h }0 X9 M9 ~+ b1 j. M
}% r1 I. z4 w% u1 W) _3 I: J \
return res;% B7 e' w: [& Z; ~' g
}) a) f7 }& n7 ~/ V* j: T" [
}+ M9 F1 G( Q! r, k) v) q; ^" R
% a+ X: T$ m# a+ H: r# N9 }
class UnionFind {
1 C: G! Z' A* w1 R! M& M- a public UnionFind(int size) {/ F/ t. A8 E/ E9 v
f = new int[size];
, D- |% \* L- o) U7 S- r Arrays.fill(f, -1);6 p1 r; H; i. [/ g( ]$ h) |
}
0 G+ v6 u8 b) o0 h1 j
/ G) J. C: ~- x+ d, M public int find(int x) {3 O/ K/ y$ J6 c& t1 E
if (f[x] < 0)0 w; Z+ z6 j' q5 X/ k
return x;# w( ~4 ~ E. C7 \
return f[x] = find(f[x]);( v, E; g. p& B* d5 @" y
}
: S) E7 J$ E8 t* R% c. a' _; A, b0 W, S
public boolean merge(int a, int b) {/ A# z/ I7 u- u5 ~& z! ^
int fa = find(a);* z( {5 k4 c1 @. `$ R& M
int fb = find(b);
) t9 Y8 J! E$ N* F* I0 d* D5 n if (fa == fb)
, G5 Q1 t8 N; W/ X return false;5 \7 c0 F6 s* \9 t
f[fa] = fb;
* h: m- I& V4 G V0 N return true;
4 Z8 m: T' @' b* R% ? }
* Y9 s2 [5 [# F/ ]. @" o* f
2 ?- R+ O. p0 h$ W- Z/ y* J public Map<Integer, List<Integer>> sets() {! B6 @' z( h( E( v m
Map<Integer, List<Integer>> res = new HashMap<>();
% c1 I1 [% t Z$ h- f/ u+ T8 D0 d for (int i = 0; i < f.length; i++) {
- u4 P& {0 q- v, C! a8 a9 A int fi = find(i);& }+ r) y% Z- ]: r( h0 [
if (!res.containsKey(fi)) {- L% |( E, x6 e3 N- H6 s
res.put(fi, new ArrayList<>());: n& E% d' w+ K% p7 u
}
; k) B5 M% ^( {% p res.get(fi).add(i);6 l B$ j* R* h$ {4 O9 q
}+ f# v$ [! T% l/ p! A
return res;& n/ e) U# {8 A# N
}
& b; Y! r7 x' B0 v9 f ~* v+ d w$ }" D4 d2 ]$ T1 d9 W# i
private int[] f;
4 g) w+ L% U* R$ u( t& h- {7 X# M4 {}9 u& n* ^# b* w- r! r: m# A
|