登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】
, R) K% }. I6 a4 t! O6 ~解题思路, ~; F0 ^; L; U) w1 n; C
签到题,循环判断即可。
- H( |! [. D3 x- r5 `2 Q" B0 H9 Q) V1 B
代码展示: }5 z6 j# u4 X& U
1 f4 g4 a6 r( x) \1 F- wclass Solution {; w7 }( S' e5 u0 f w
public List<Integer> targetIndices(int[] nums, int target) {
* E4 a9 D7 x/ f1 }0 S Arrays.sort(nums);
8 V/ e. b" R. N) u0 V0 @ List<Integer> res = new ArrayList<>();( D0 x" f& V6 a6 g
for (int i = 0; i < nums.length; i++) {
0 g" X* N6 s7 [6 k9 ?/ K. _ if (nums[i] == target) {
- y( c" w3 V$ y0 [/ e; [( ^4 ~- h# J: H res.add(i);
: M+ b/ P7 @3 V. Z e: K/ ~5 w }
+ D) a; q% ]4 e: y* m( l3 v }
0 A6 [' {9 x! W. }$ z7 i return res;" Y6 Z# ~! t- r& V; A
}- M; q) W- L B, v- f0 j3 f
}
: d) f+ E' q7 X& \# `
! h! y7 v3 t1 D0 v【 NO.2 半径为 k 的子数组平均值】
; |- X$ @0 g! c i+ I* ]' U解题思路% H8 }+ ~$ U& g- f6 N
使用前缀和计算区间和。注意使用 long 类型以避免溢出。
% Q* I" q" t0 }5 l# X7 S D$ r+ {2 ^* {8 t# ~# U, b: {
代码展示' O1 }9 X- l+ \, Y7 L2 k4 n- W9 V: N
+ v# r' m# E9 N( U, Oclass Solution {4 @2 L( J0 Z& z4 f% ]! M, N+ `5 L8 c
public int[] getAverages(int[] nums, int k) { a% l/ Q1 @+ y1 R
if (k == 0) {5 B3 Y$ ]; z! r3 K7 J9 h
return nums;) ~( ?$ p/ n/ o) a% ]
}
4 G* b8 H5 }/ n long[] preSum = new long[nums.length];
0 N+ J& e7 S& N+ q; Z preSum[0] = nums[0];
) ]" ^ ~5 i, G8 W# g for (int i = 1; i < nums.length; i++) {
}" h' F. W! K. `" b& c preSum[i] = preSum[i - 1] + nums[i];2 U. ]0 {6 C) d! f/ G
}% B4 F9 w6 _- y/ o7 ]$ m, Z
int[] res = new int[nums.length];
# X- f: W' w4 l a Arrays.fill(res, -1);- P9 Q* M& q9 Z" t9 d" q
for (int i = k; i + k < nums.length; i++) {( {! Q/ o: U5 b7 j' ~# }& P6 Z' i
long sum = 0;
& x9 T" b% S- k! W: H8 v if (i - k == 0) {
+ J: q2 f9 S! i7 T X* J7 S; Z6 I+ T sum = preSum[i + k];# a. A4 @! p) T
} else {% u' W9 Y9 ?7 J0 T/ n
sum = preSum[i + k] - preSum[i - k - 1];
8 `0 }! _$ l# `. n, ~8 ]2 c x }
. k6 [: d5 ^% B% g! k res[i] = (int) (sum / (long) (k * 2 + 1));' I4 C P: R0 m* K# D
}
/ Z# f3 k$ a% G return res;
( d" \3 x( P) { i( P0 i }/ L( K: d* p5 z1 \8 e7 G
}
. m; N) I W7 r+ g- G8 Q
1 x; ]' ?: f \, i1 d【 NO.3 从数组中移除最大值和最小值】1 L- L7 ]3 }- Y0 g
$ X N7 e0 Q, k1 {5 B: d解题思路7 ?7 z2 |7 f" r$ Z" C [
贪心,按照最小的花费移除即可。详见注释。
# R+ y3 n8 Y$ s6 m d7 j0 X; I
8 \' r$ U" _* L5 f# s# J/ I代码展示
2 x- p) k# @& @: Y& V4 B( F3 f. b8 X: x* b. [- C
class Solution { [, g. H6 w0 N' \/ h4 Z
public int minimumDeletions(int[] nums) {
/ ]: W5 Q+ ^! u& d# F- s' \ if (nums.length <= 2) {% e3 \* V+ y @8 W% t. ~0 v- z6 @: W
return nums.length;3 U; t' _7 ^1 L8 n% S. `% e' D
}
, a+ n7 z; @5 C, H8 o8 G // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
; O9 o+ G+ t& }& ]! a int min = 0, max = 0;
0 z9 K( b* P8 L! N, u for (int i = 1; i < nums.length; i++) {
# j, x; p$ T8 N if (nums[i] < nums[min]) {1 t/ b3 B/ P1 b, a; i
min = i;
- V( B8 ?" |2 u) U: Q% X }
: V; z. J; D1 r# E if (nums[i] > nums[max]) {
% R( b* P; h3 N1 S7 ^ max = i;" k! H9 _& y3 F, `" O, A/ Q. E& _. t
}7 o/ O. R0 y. N, x" h3 z5 P. z
} c, \6 o9 u+ ~9 c2 W
// 要移除的元素下标为 max 和 min
: T I/ j% C8 `2 G3 m // 此时我们只关心下标,谁是最大值谁是最小值不重要* Q/ `) e0 }' h. y9 f8 b# I
// 为了方便处理,令 min 为较小的下标% Q& n1 _& \$ F. T9 n" O9 p) i) i
if (min > max) {
( O: P) h6 L% v ^ int t = min;
( y, X3 L& x3 B8 R; w1 z3 p min = max;! o9 p( c# g* u$ O
max = t;% U& S8 ?) n6 ^& X; O: R
}2 S8 W( ~5 `! W! o" b) A8 Y
int res = 0;8 }$ Z$ X3 ]$ D' V6 k
int left = 0, right = nums.length - 1;' \$ i* N% N6 b& f7 x
if (min - left + 1 < right - max + 1) {
8 a$ f" X% K0 C3 h" F& {$ M# @ res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
) `% g& _1 O% R9 A | left = min + 1;% x# U7 B; S2 c9 {/ Y" Z0 M4 f, R
res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
+ ?! \/ r) [& p# j; ^* g } else {/ [6 {1 o; O* W
res += right - max + 1;5 P; i. J( z# x! v: S2 }" P! C
right = max - 1;
& ?. h6 V4 ^ }& p% l0 w% r res += Math.min(min - left + 1, right - min + 1);& L3 _% U7 m7 R5 `* _& }+ X
+ ~ [/ N! Q# g; T9 d- ] }
" I4 V5 g u: r- A return res;/ a( s3 S% v; p0 C
}
( u2 c9 [# v, M) D9 C* a}
" w+ S! q/ \8 p7 C# T) u7 X6 B" k
【 NO.4 找出知晓秘密的所有专家】! {/ _3 O# @- G! E/ T- D( ~
: h; K; }! a7 y/ E/ ] k4 p6 \
解题思路 C5 _' ?, d: R" A0 t& z
并查集,详见注释。; o7 [0 l8 [2 T& b
: _; B2 B8 k1 u6 E2 z0 V& l代码展示
% H- O! b% K! ]" c/ e( y
$ C5 ^$ ~8 `5 f, {* l! O/ _- Yclass Solution {
' A% d/ X0 }+ l' A2 F public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
/ F6 ?" z5 i0 K* u; G" T" W: L // 按照时间点将会议分组
* |" U( q) M* B9 U1 } TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();7 U5 U) V$ C3 Q- A, @. `
for (var m : meetings) {
* c/ B' A. c$ E/ [0 F if (!orderedMeetings.containsKey(m[2])) {% w1 T0 M9 k0 ~, ]9 Z! S7 _
orderedMeetings.put(m[2], new ArrayList<>());* u+ S% B* h0 O& d+ ?, N
}$ V. }( ^1 I3 c/ ^1 e7 N
orderedMeetings.get(m[2]).add(m);
1 J, }( I$ o/ A2 V8 D% r }
' b$ U1 @/ m2 q4 ^* ~. M8 Q! f boolean[] known = new boolean[n];5 B2 L( W/ H4 |
known[0] = known[firstPerson] = true;& Q9 s' S. ]0 n3 p
while (!orderedMeetings.isEmpty()) {
9 n9 W% J7 ~) ?0 f8 j' E; z // 按照时间顺序处理每一波会议
) \1 H/ P/ r' M; ]- y) ? var entry = orderedMeetings.pollFirstEntry();, g, A0 z+ r* K' n* w
var curMeetings = entry.getValue(); O+ f3 t4 y' G; C& t+ g0 w. O- a
// 使用并查集维护当前时间点发生的所有会议中,有关联的人
( d, o& l8 |. c- ~4 c* S% A& } UnionFind uf = new UnionFind(n);
, T5 w$ J/ s$ |3 f for (var m : curMeetings) {7 n2 I4 D' w& d7 H
uf.merge(m[0], m[1]); t0 f6 Z8 i* M0 V
}8 p6 c' W* P7 b
// 枚举所有会议
$ L/ ~% P- w ^; n, [4 W* ? // 若会议参加人 m[0] 或 m[1] 知晓秘密$ `5 x3 g; N! t( g9 d+ J" ^
// 则把他们所在的根节点也标记为知晓秘密
7 P: k* {7 W/ R& m. |# O& `9 A for (var m : curMeetings) {
& ^( U: u% D" S+ F( u2 N if (known[m[0]] || known[m[1]]) {0 x1 `7 \. `0 _9 P
known[uf.find(m[0])] = true;
% X1 |& {- a4 X1 H+ ]1 ^ known[uf.find(m[1])] = true;
' o8 L/ q- D9 N7 H5 _1 _% k }
. S" C) }$ B) R$ N }
2 l5 P" P B" e* L+ o // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密! {" Z) B" \( K+ N
for (var m : curMeetings) {5 A. b+ R |, s% f: D
if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
6 t ?& g; E# S* C( o! @ known[m[0]] = true;
+ r% Y# D. y+ ^( `# v, y9 k1 t known[m[1]] = true;2 k" p% d6 p; o
}$ o! q4 V0 v* a# ~% p$ H6 T2 p. ?4 e
}
c4 G# w- Z/ Q' ]7 C5 } K4 h }1 s1 C2 ~2 v( j
List<Integer> res = new ArrayList<>();+ z2 Q' ?$ `9 q, E
for (int i = 0; i < n; i++) {
+ [% K4 ?& }! [! V+ l if (known[i]) {6 U7 I8 Z, X3 d+ |3 G1 v1 M
res.add(i);5 k5 C0 L: ?7 S
}/ @* o, v/ y' {' `- ?% y- {
}, x! ?+ y! S& `* y' R. F2 h
return res;
) l! F. T9 v1 m }0 Y [; E3 r0 z4 _, d& v: N
}
+ ]: I4 z8 l2 {6 w" M% k' i5 H+ Y0 _* ^* g* r* v
class UnionFind {- V2 M6 S7 q, E7 k6 o3 C5 H
public UnionFind(int size) {6 |/ ?" I R% c
f = new int[size];
) x J; [$ n) `9 n! F# |; m Arrays.fill(f, -1);- u0 U# T( m9 K+ k8 s
}& o7 ]6 F' ?" V+ }
2 o+ z+ @0 S K- c, T public int find(int x) {* o- ^- j, d* p4 S/ \6 |4 }
if (f[x] < 0). x3 \- O( E/ @# y
return x;
7 c3 _9 `2 ~% b9 X! C7 T, { return f[x] = find(f[x]);
5 ~/ O. |: l7 f4 l% ~ }. U; L! G% `% N3 T. r# b# U
( n& w' [; A$ V! `6 \4 g! B public boolean merge(int a, int b) {0 ~" i/ q. Z; g5 ]. P
int fa = find(a);
2 _" ]# h% Z" n1 \, C int fb = find(b);
" U$ K$ w6 o7 K' N- g if (fa == fb)+ V! P% b# }, T; g% n
return false;- W6 o0 I8 o* `' ~# H/ R" f3 {
f[fa] = fb;8 x$ b0 A U8 ?& c1 x' {9 Z# ]- V: T& N5 X
return true;
1 d4 M# N3 _. z1 e0 ?. R }6 \! v) J8 H% I' g8 L' w( I9 Z
* H' D4 h+ g8 [# @; v( |7 u6 P4 @ public Map<Integer, List<Integer>> sets() {- s) E- B4 }* t5 ?/ n
Map<Integer, List<Integer>> res = new HashMap<>();
3 I+ M: b9 f) I3 L) j for (int i = 0; i < f.length; i++) {
* I9 Z0 }# R+ H4 ], C int fi = find(i);& w! v' p2 p/ X6 \" r
if (!res.containsKey(fi)) {9 ]# T! v m9 A* a& z. s
res.put(fi, new ArrayList<>());6 M7 ?1 G8 U8 D) Q$ Y' m( v
}5 b- q2 B! A- P- W3 M2 M+ c% e
res.get(fi).add(i);: r; m* V6 b+ [; B
}7 W% S) s" A( Q$ Q$ v' L- u: |
return res;( P, s1 i3 X/ O+ F: \, n
}4 ^. S s, ]4 Z) g1 }& A# a1 q0 I
9 O7 j- Y' O; R( W7 D7 X
private int[] f;
: G @: C: l0 j5 d' L) d$ e( S' X8 Z4 l}$ z2 _! ?8 t0 }
|