登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】! G* o, V" T! A+ R$ N3 _
解题思路
% Z j: y( V( e4 V# M7 Y/ T: b签到题,循环判断即可。
0 d% R. o; G; c4 Q2 W8 A- U4 k4 J3 S' Q/ `. y% b
代码展示$ o! x2 Q0 l0 h' Y, w7 a
; Q) F* Z: C: {) q3 x. { e
class Solution {
% u7 @* K- K) q* W' R public List<Integer> targetIndices(int[] nums, int target) {
& p$ h# {) t7 l. f/ b6 d) B Arrays.sort(nums);' ^ y& Z2 _ m5 a7 f
List<Integer> res = new ArrayList<>();
9 h+ X. Y* s& n) i# M for (int i = 0; i < nums.length; i++) {
( R$ G0 W0 E+ \8 X if (nums[i] == target) {
5 w. s. ^+ b! k3 m. P$ L( H0 {' O: |, m7 f res.add(i);
5 n9 S3 e. E2 f }* J. k0 s! s' ], }1 S1 q+ f) ^& M
}
6 }% {8 F" V" ]# y, A7 G+ a return res;/ v7 L8 ^/ D0 D9 p- I
}
4 U* x* k. N+ T: W}
& M2 z% q& `, @- w2 p. M
) Z0 c& ]' d* {9 H【 NO.2 半径为 k 的子数组平均值】
9 m& H. U; H. H- ?解题思路9 X, ^! e1 j1 E! R0 j
使用前缀和计算区间和。注意使用 long 类型以避免溢出。
0 \* [' D9 x0 o1 ~5 F8 S# e5 e F; H2 X
代码展示) }2 j) y6 I" ?( v1 R
/ [! i: h1 M: @5 [7 J: r" @
class Solution {
2 F! F5 R. ]: V5 _, V. m public int[] getAverages(int[] nums, int k) {
3 b* P% \( Q% y0 {' g* @' X4 l, ~ if (k == 0) {
8 _( w) ^ m" u; O& e3 y return nums;3 Z/ r% Q0 ]- ?- Z* H
}1 h- e6 s8 c) ?) c) m7 u% S1 G) M
long[] preSum = new long[nums.length];8 A( S( m" H# ^+ K
preSum[0] = nums[0];
& Y# f& M9 I" S: _* l. F for (int i = 1; i < nums.length; i++) {' Z# M* l. g8 Z2 u& H
preSum[i] = preSum[i - 1] + nums[i];
0 S! q, F* \; P& \ }6 Z" q0 k& H3 R! Y7 E
int[] res = new int[nums.length];% x t$ @' y& C# S% Y: j
Arrays.fill(res, -1);
; [! l. y6 \ a& w- |3 R for (int i = k; i + k < nums.length; i++) {# H2 @0 u& |. f8 ?" p+ U& U+ M
long sum = 0;0 g% E* P. h/ F3 _ Y
if (i - k == 0) {- L9 d/ N( N: q
sum = preSum[i + k];
- E( u* u$ ^6 w5 Z$ M } else {) G( F2 M! j. u& b/ }
sum = preSum[i + k] - preSum[i - k - 1];# e' G3 A4 z8 \9 P9 U% D" U1 L6 ]
}, {/ y- l9 _: N. d
res[i] = (int) (sum / (long) (k * 2 + 1));5 V, [* h) a- h5 P$ K8 E
}
0 }: H6 l1 U& f. k6 I- e return res;7 q. W* _# I- c% B" r( B
}6 V4 @& R6 H9 r, O u5 ]" F) R
} y( y, B Y! G3 T, A
! w9 g$ j" ^- O6 ?【 NO.3 从数组中移除最大值和最小值】* b7 v- q+ o& e' O# X: w7 j9 \- X$ ^$ g
, b3 f# U( r# `1 p解题思路
6 p9 G ~3 ^. r# D+ P8 ?贪心,按照最小的花费移除即可。详见注释。3 |; g5 K) z7 i
1 M8 v: F/ f) b0 k9 n8 C: a代码展示
7 y1 \' |8 o1 C' G) o3 `: f2 \, G5 @9 z8 r
class Solution {
' i5 C9 m0 v! s2 X, D public int minimumDeletions(int[] nums) {
7 W: r9 ]* c" _! f. Y7 ~. H if (nums.length <= 2) {- I: t3 _9 a: E9 u
return nums.length;
9 I& C! I. [! t ]$ n, G; y }9 N8 w1 ?* V% h! |' [1 y5 b
// 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
4 T# |8 h4 a$ P int min = 0, max = 0;+ h0 u, I0 p9 N
for (int i = 1; i < nums.length; i++) {
$ r9 N& i8 f7 v7 r% z' ? if (nums[i] < nums[min]) {
S$ d$ E* a# r" o5 A min = i;7 k( h7 M' P$ ^
}& R: ^ E- E! i3 p% }: O2 Y
if (nums[i] > nums[max]) {' ]2 {% ~& M( B5 V, k# E
max = i;
, A3 Q4 s& R; B' F: A3 i2 ` }
' D# Q) d8 S4 A8 u. T$ Q! s9 W& T }
8 M |8 h0 F2 ]. P // 要移除的元素下标为 max 和 min" e4 ? Q& D7 @6 K' s
// 此时我们只关心下标,谁是最大值谁是最小值不重要1 E2 o9 |* I& n# `9 M p
// 为了方便处理,令 min 为较小的下标
( y; t5 }0 P4 ~) u/ l- I if (min > max) {
& s* Q: Y( j8 W( |9 Z2 { int t = min;
2 }8 W. D" Q) U min = max;
3 Z" M2 I: a, ]4 d* O) Z max = t;0 q( x2 J) S8 w% k: K" V
}
( [$ u7 R" ~6 |2 w2 v; W( x int res = 0;- B6 z" t+ N9 ~- S: \/ ]
int left = 0, right = nums.length - 1;
5 k" p. E! i% W0 E, k5 B$ P) }: ~2 | if (min - left + 1 < right - max + 1) {
. E( G+ d. o6 X& O res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min9 Z1 v3 _* r. g: v' P' `
left = min + 1;
8 p) o' ~% S& u( y6 q# ~ D, W res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
$ U; x( @5 Y9 k9 W( p } else {
, R5 H" j" P) p res += right - max + 1;
& E; i7 J: F/ [0 T right = max - 1;
2 Y, c) A( O' F$ [+ |0 O. U: Z2 f1 ~ res += Math.min(min - left + 1, right - min + 1);
3 A9 ^. Z0 r/ i X! ^0 p' j, K, e7 W/ L, O7 T" r
}9 r& B8 x! j" `% E0 H) N
return res;
' m8 t, R. @& z* n }
9 R3 N* J- E9 n5 n9 z/ {% @9 B; \- }}
: Y9 X# B7 U' Y3 A7 L; D5 I: x
% V. G1 E. [/ W8 n7 u【 NO.4 找出知晓秘密的所有专家】
: @! X0 R; ]! _; ~2 g9 m" [7 X; D
解题思路
* u7 J" u$ x. P# s9 ]& y并查集,详见注释。
$ M( \9 L+ P4 d5 c4 a h4 F G; X S' V0 E! S9 V8 G; D1 j
代码展示
6 T. l3 ^: |/ M' v% N2 \2 n M$ w
# l8 K7 K4 J9 z! P @7 ?' `8 x$ y: Bclass Solution {+ U% Y9 ~( ?$ r5 u
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {9 M/ O+ H3 r* }
// 按照时间点将会议分组! Z7 B9 P0 a' h3 W
TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();: b" O3 M4 J2 b4 H: c; C( P
for (var m : meetings) {- R& Y# H- o' E. U. P
if (!orderedMeetings.containsKey(m[2])) {
9 E1 Q+ C" J* V3 M+ n orderedMeetings.put(m[2], new ArrayList<>());! F4 A# p; \) t& ]/ k: D
}1 r) j/ D' q6 e/ m
orderedMeetings.get(m[2]).add(m);) L1 a8 u6 Z# p1 [6 W( W
}0 y% p8 f6 ~. H* F
boolean[] known = new boolean[n];, Y7 ?9 D0 P* S
known[0] = known[firstPerson] = true;
" r1 I, e8 t$ O, `4 h7 h3 |. K' I2 o while (!orderedMeetings.isEmpty()) {) S. u9 F6 b! A: J
// 按照时间顺序处理每一波会议
' ^! t- N( C! }9 S4 y# v var entry = orderedMeetings.pollFirstEntry();
- l9 }4 Y! x. H3 P9 K var curMeetings = entry.getValue();
5 V @/ ]8 H6 R% w // 使用并查集维护当前时间点发生的所有会议中,有关联的人+ e, x0 e6 X% P) Z% s. Q6 _* @
UnionFind uf = new UnionFind(n);* K! J0 N% F7 y' ^& ^% h Y! X
for (var m : curMeetings) {) d8 g7 ~. u$ J! }6 m/ s! G' A
uf.merge(m[0], m[1]);% k1 I! \+ P$ T9 ^% A5 z
}+ z4 {+ I4 I# ^: [4 [4 G
// 枚举所有会议
m2 @8 @5 T Z& V% r- O // 若会议参加人 m[0] 或 m[1] 知晓秘密% T5 L, {1 P. V0 E) m3 e
// 则把他们所在的根节点也标记为知晓秘密
5 {4 [8 i4 F6 G9 J4 G1 z7 k4 E for (var m : curMeetings) {
4 f% L( [/ ?0 I9 H& H, i if (known[m[0]] || known[m[1]]) {
2 R- }( t+ I4 O known[uf.find(m[0])] = true;
; x4 i+ m' V/ t) V8 n known[uf.find(m[1])] = true;+ K! z! c' j& c8 d* j7 m. s
}
$ m& G0 T) _9 q# K9 C( P: d }/ Y4 K1 G8 p: @
// 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
/ o0 n7 U- A$ O2 H" h for (var m : curMeetings) {0 M8 K- |. _! K
if (known[uf.find(m[0])] || known[uf.find(m[1])]) {1 L/ _- B3 P1 d: K4 [2 G4 E
known[m[0]] = true;
6 g8 m1 M1 u( e: X known[m[1]] = true;
K; k2 N/ r* F7 o( h4 X) n }) l: e, m* o1 u
}
7 W3 W1 ^+ G! p9 ?: Z* b }
# g6 Z) f9 s& ?; R( o- ~0 N List<Integer> res = new ArrayList<>();, M; M& P9 k$ L* J
for (int i = 0; i < n; i++) {6 Z1 k: k! R, s/ _
if (known[i]) {
+ i( ^% U% S$ l7 @6 Q5 u res.add(i);
( E. V: J# n/ q' w. W( P }, O, \2 u3 _4 F6 ]$ W: R* P
}4 X& p! B! B& G! T/ Q! P: t
return res;
9 K/ T1 L, ?4 H' M2 O }1 R7 j, v [0 V2 A6 a+ z+ i
}
5 ^( l, f# u( F4 s4 ^9 B; F w) |2 k( k
class UnionFind {
8 i- q- m6 l" Z( o0 j( v public UnionFind(int size) {. V' E- T! P% l; Y/ s* Z, V- w0 ^
f = new int[size];
' c; d7 m* I" y% ` Arrays.fill(f, -1);
& T n! N1 g" P, i' V; ]" ^* \ }
p! w x9 D0 t& Y2 S! P D) ^2 B" l5 W, B1 J
public int find(int x) {% ^+ S. s/ P% o! ?$ B# e
if (f[x] < 0)
2 p4 a& a# l/ o O return x;
, U- ?: s$ ]2 P return f[x] = find(f[x]);
: m V+ L. G, Y6 \5 {7 y! S }
- Y* m/ E. ]& M6 L! S+ R1 ~7 p8 v1 I$ T- K
public boolean merge(int a, int b) {" {0 v/ E3 h) q/ M1 Y! h b; P
int fa = find(a);
: b: }; h+ M1 x1 g: P! u1 S int fb = find(b);
7 f6 H: N( v1 j5 } I5 d if (fa == fb)
/ N5 ^) L! Y' |2 e$ P return false;$ Q) @: i1 w3 q) t
f[fa] = fb;& q( Y$ l0 E A* K$ _/ v$ P% |% E
return true;
" N# y' T, a: m7 U* J& d E, `" | }# f) r6 n% l$ S
]; k$ o; R0 @! D7 k% h) W0 F public Map<Integer, List<Integer>> sets() {8 _8 ^$ k3 D3 G( {9 S4 o0 B
Map<Integer, List<Integer>> res = new HashMap<>();! i' X/ V. t$ P2 y4 u
for (int i = 0; i < f.length; i++) {
; Y; m6 e5 X# c1 h9 E int fi = find(i);4 U; p; ` I: ?* i, |+ ]- L. e% x
if (!res.containsKey(fi)) {5 I8 k5 E& d2 c! l# }2 T
res.put(fi, new ArrayList<>());
7 G# g7 [& j# u# w; |6 B }
) }, J- v; Y) G# e8 f res.get(fi).add(i);
, m9 N3 @+ J: z& F8 F" u x }8 c* ?, `5 Y, q, Y; P
return res;% I# R, \. u9 T- n \' Q
}9 }' V6 E9 B0 S' O- J+ N
" U# |+ i( b K8 c! Q' a) F private int[] f;
' z) f8 F$ w3 l}4 k: d; I; z h; | p, G
|