登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 找出数组排序后的目标下标】
' t" `! K0 k) k9 S3 N% r8 l解题思路
" [; R: U N' | G签到题,循环判断即可。
7 B2 `# K/ L, E" P
9 Q Y! B7 \+ v# V" d. i6 n- J d* a代码展示
' i& X9 d% y8 u. b* ~0 p: `! |+ K' A0 w# q- n
class Solution {' y9 Z5 P( t9 U/ P, {3 i
public List<Integer> targetIndices(int[] nums, int target) {7 S& A" r) L4 G- m) ]$ A
Arrays.sort(nums);
5 f! k$ J$ g5 Y0 D ~ List<Integer> res = new ArrayList<>();
/ C1 p$ q- v5 i& s& \ for (int i = 0; i < nums.length; i++) {2 J' A; t, i4 ]! x/ u, L2 M. u* G- W
if (nums[i] == target) {) a- w: k1 q$ ~, M" [" D
res.add(i);
+ `* j, b; \9 G6 _/ ^0 H }7 h' I1 W; J% R7 A; w: c) e( b
}
. l9 ]9 W9 B! e# y, Z return res;
5 q0 I+ L' r5 M }
' b9 b0 S7 Q+ w( D: P# I+ u2 X}
& U9 K4 ~! M; j5 I& S, ?8 I4 O7 {, x1 G( V8 r. z$ I
【 NO.2 半径为 k 的子数组平均值】
9 l' B) U9 o- p/ ^" o( u0 N# R; }解题思路% L* ~2 c# K2 n( v
使用前缀和计算区间和。注意使用 long 类型以避免溢出。! F8 ?8 G. L: J Z( Q: A. z' T/ T
2 Z2 z3 c# ~% k, U$ \' ~3 j R6 Y8 r
代码展示
. t) X1 w: p+ @! T: G) e* z: x8 t: \; V D
class Solution {
6 \; ?8 E9 a- F+ m/ J2 u- P public int[] getAverages(int[] nums, int k) {- H- E0 @5 {; [. F7 z6 O
if (k == 0) {7 P' E! E* g# Q( H* D7 k
return nums;
7 t" b7 ~% L4 @; S }
4 z. i* J, |5 f2 h5 ?8 m long[] preSum = new long[nums.length];( h/ M: M! }9 d: R/ }7 l" }
preSum[0] = nums[0];
) L0 ? M( D* I1 e5 F for (int i = 1; i < nums.length; i++) {4 x& H2 v* n! P. b
preSum[i] = preSum[i - 1] + nums[i];' {5 r: \1 F2 ]" _) c
}# D% ^) n' H/ X0 y+ V
int[] res = new int[nums.length];
+ `+ ]* }+ x7 ^ Arrays.fill(res, -1);
' W8 t; A) e6 g, m4 I% e& Z( F for (int i = k; i + k < nums.length; i++) {
: M" [+ Z: x6 D1 K9 ~; C5 n; D8 | long sum = 0;* S8 n; s7 ^0 D6 x; \+ V% A
if (i - k == 0) {, K0 D+ v- z: O
sum = preSum[i + k];
3 n: B/ `2 D0 G0 B9 M; L' ~4 c/ | } else {
2 e4 i; G, {6 f0 ]' e" B sum = preSum[i + k] - preSum[i - k - 1];
% a r. W$ Q1 o( b, x4 P" }3 @0 p }
. s6 I$ z) c! e" u& [7 p" \9 h res[i] = (int) (sum / (long) (k * 2 + 1));
- @7 n7 R! R* c3 Z. g6 C6 D }
% K" |$ T. v3 N9 G9 U return res;, V! d l+ [; k g; s# w
}3 A0 j J* Z5 F4 W3 A. _. q. i2 w
}+ }7 s6 d+ S& ^9 R+ {& j
2 _) \9 D7 V4 y. f$ s5 ^0 \【 NO.3 从数组中移除最大值和最小值】
) O4 B( G% J& U8 Y+ C
! V$ ~; X; z6 a# f7 ]9 ~" h解题思路
. q6 v5 @/ ~; X. A7 j& p$ t贪心,按照最小的花费移除即可。详见注释。4 H. I4 _2 w ^
0 ^# [+ w( g+ x$ }2 G7 X' f& [* r代码展示
S) M! Q+ |8 N: \/ q8 ]! M
3 }" N* k! I2 |4 n# Oclass Solution {
; E" y9 z. A8 w# a+ ]2 e public int minimumDeletions(int[] nums) {
& P% w% X# B7 J3 s, ^5 M if (nums.length <= 2) {
3 {* ]& U% {/ G5 C return nums.length;0 N, u& @7 l% x3 [: d2 B
}3 {/ I- V+ N3 R9 ?; v/ l
// 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
5 H$ v& |8 O' j& \7 y int min = 0, max = 0;/ q6 V+ f/ m8 o2 V/ Q5 @" q
for (int i = 1; i < nums.length; i++) {
8 U4 C1 w: i1 `" }& U! _ if (nums[i] < nums[min]) {
/ O. w: S( }4 F7 I% ? U) M min = i;
|* Z$ M/ h' z' C" X5 d/ N }
" E+ a X# K m9 S if (nums[i] > nums[max]) {# w' @& }8 a( A) b4 ?+ p- @
max = i;
) O+ i9 z6 B0 J7 ] }
3 f+ g) a% W' q8 z- M& S& E Q }
; \+ S& h6 t9 f // 要移除的元素下标为 max 和 min: L. Y1 U0 b& ^% ^- z. |8 A+ N: M
// 此时我们只关心下标,谁是最大值谁是最小值不重要. Z+ q* J* v+ i3 G' A) f. o
// 为了方便处理,令 min 为较小的下标) F5 K3 g2 J& U4 d- @# w( H
if (min > max) {
0 s# e, ? ?2 E; J int t = min;
1 ~6 O7 N4 f' w* Y min = max;
0 w, M% o4 \$ V0 w; [* k max = t;
5 P$ n* \$ J! b$ H5 w- {& f2 K6 Q$ h }
2 ?7 j" `" Z" l( h% _ int res = 0;
, o: _ P: q. a& o8 K: e& l int left = 0, right = nums.length - 1;
; X/ c' F* ?) V4 c# x' R if (min - left + 1 < right - max + 1) {1 g5 k( U1 Z0 M* u3 O3 I2 U; R' M+ T% s
res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min( g* D% S( g9 e" {6 o
left = min + 1;* N x% C+ V( C9 q; g
res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max( B' y* W" K& T8 W
} else {8 p* m2 Z$ i7 f- \1 i& n
res += right - max + 1;
# t9 \+ ]/ l+ L0 y) {* y9 F# q right = max - 1;
( N6 J c% x; W' u: C. F" ` res += Math.min(min - left + 1, right - min + 1);3 }% s' v/ Y4 M0 h/ c5 H! [- y
& s- b' ]! a5 X v9 Y }
7 b C5 W- A* H* `* l return res;
! P; s. P6 a# w8 @7 ? }
- b& L# G0 F9 L}4 Q) h' G# C# w
7 v# ?9 i$ K# e$ b& p9 Z4 g8 ]
【 NO.4 找出知晓秘密的所有专家】
8 v) \) |. r( _# N+ r3 Z
* O! y1 n/ T5 E! E! k解题思路
8 [: \" V) j+ }0 m6 ^# x6 Y并查集,详见注释。
8 J- y( X9 I# ?5 c$ o) _8 [- u, \: r- y
代码展示4 b' X" v9 T; S! X" }! w3 h( z% d
5 H! \ U8 y) e( b# \class Solution {
5 q) j* _0 ]3 g6 u4 ^! [; X public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {# z' ^. F6 c2 N0 @
// 按照时间点将会议分组5 U! H I0 p& _& f+ B! Z
TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>(); S- l" o3 ]/ E
for (var m : meetings) {
9 D8 H) S* e1 x* Z" z5 m" h if (!orderedMeetings.containsKey(m[2])) {
) @# [, d0 a' y% ~* r( I$ W7 O( H. p# e orderedMeetings.put(m[2], new ArrayList<>());9 f( H3 A/ k, g V' G
}& Z% G6 ^5 M$ f& p* M- B
orderedMeetings.get(m[2]).add(m);
2 [3 M( j) b v, g }
4 j4 J6 F) L& x boolean[] known = new boolean[n];& J4 U+ E5 E$ {! S/ | y
known[0] = known[firstPerson] = true;( g6 d7 {9 {7 x( \0 y* h+ u4 i
while (!orderedMeetings.isEmpty()) {( \! y" Z! f! Y
// 按照时间顺序处理每一波会议
4 S6 C7 X) h; O3 J! m, u; ]& b1 M var entry = orderedMeetings.pollFirstEntry();5 T! H$ I( k3 K) q& f
var curMeetings = entry.getValue();4 u0 y$ a/ j$ w% Y
// 使用并查集维护当前时间点发生的所有会议中,有关联的人& j+ s/ o0 |# \% ~2 X5 ], ?
UnionFind uf = new UnionFind(n);# o" Y$ ^1 e0 q6 o" P& Z- u
for (var m : curMeetings) {
9 [- z l$ n8 w1 r! ~) Q uf.merge(m[0], m[1]);
9 a* w! w' g# j) _9 q. t; G }* r( T; b3 I& r( U
// 枚举所有会议
% |9 |1 |9 g ~; q' O1 q J // 若会议参加人 m[0] 或 m[1] 知晓秘密
3 x! g! l q0 G1 ~, E // 则把他们所在的根节点也标记为知晓秘密" |3 s" f: m$ x, r1 |; n3 o
for (var m : curMeetings) {$ E# S6 E4 J$ D7 p/ I
if (known[m[0]] || known[m[1]]) {( a2 m% h0 {3 A+ d- A
known[uf.find(m[0])] = true;6 F) K1 }, {3 y3 ^: n, p- J! C
known[uf.find(m[1])] = true;
8 @; v4 N5 c' l9 [4 Q }
% e" _) N6 Y9 [ f) _ o: U }1 I& E$ j. y: d6 i
// 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密( n! i4 b4 F% y! [1 g0 U
for (var m : curMeetings) {
; s1 X$ ^% ]5 Y if (known[uf.find(m[0])] || known[uf.find(m[1])]) {0 n. ]8 p3 ?$ y5 Z. t5 X$ ^
known[m[0]] = true;2 ^" ~2 V& s- c0 d
known[m[1]] = true;& B$ R0 F7 @1 ? R- T
}
1 E$ G# [9 _. e7 U: n- u/ e }
3 P! L$ {: d3 }0 H+ q: f v6 x- s$ p }
$ h- ?' F) i* t( I3 C9 ]9 M/ J List<Integer> res = new ArrayList<>();% }! `4 H9 N) m4 }) {8 p% m
for (int i = 0; i < n; i++) {
9 t x( b. B& A! H+ [ if (known[i]) {
9 Y% V. M# p- e+ h: p b res.add(i);, }* x4 X. g2 B5 r+ v0 z
} I$ }5 c' [! V6 o# c3 c. c1 D4 _0 K
}
- B& c7 n0 _& d9 y, D return res;. [4 P0 E, W" q% |* P* c M
}
% f' ~( ~( J; M( _}
/ e4 R0 m6 c* C3 B/ o% X& ^# h2 N# V$ y% N( C
class UnionFind {
O1 E5 _2 M( u* }/ N9 F public UnionFind(int size) {
! o" X8 h- |2 D! a4 C5 j' o; a f = new int[size];
; l, d9 m* @9 R: ]2 X1 \9 W, O Arrays.fill(f, -1);) x* M1 Z1 {: c/ r( }- p1 G9 A1 c+ j
}# ?4 D# L; W I9 d* F: F
8 s f- B6 t* Z' ?
public int find(int x) { X- @2 g, i$ |9 O( s
if (f[x] < 0) I' x& C& @; [. g" v3 P+ \
return x;9 P5 k- n% h; V4 y# r# S' f$ E
return f[x] = find(f[x]);* G" N; Y! s/ A: N U- A" X+ o+ n. R
}
3 M# C. Y! j0 _. }
* V3 l3 w0 e; z/ _0 ?$ R public boolean merge(int a, int b) {+ `+ u! E ^2 J% P: _+ R
int fa = find(a);
) ]0 d( V O7 Z! B int fb = find(b);0 C4 Y! t: W" r! x
if (fa == fb)
{ c0 A. n3 _6 j3 i return false;
4 P( v \ P7 y, g3 b# ~, B# ` f[fa] = fb;
- J: P5 T3 u: d6 F" p. b$ Q return true;
; P& J2 n* S' P5 }) }: F }) b; i7 C0 y& O% i' V
) B9 t" G3 Y/ {# l
public Map<Integer, List<Integer>> sets() {
: r, ~3 b4 j" @) e$ _+ r0 f' f Map<Integer, List<Integer>> res = new HashMap<>();8 k! U" q v& ]$ z* o. u" P
for (int i = 0; i < f.length; i++) {1 M9 R1 w! R- X# p, t
int fi = find(i);$ z3 g4 V4 S, _. E1 k! J$ t* H
if (!res.containsKey(fi)) {
+ B$ H W# V+ C, H res.put(fi, new ArrayList<>());- Z4 W3 V9 A- h% [, g
}
5 [2 v$ K. F) X( J; c/ v. b res.get(fi).add(i);
5 S' h# q, N+ M+ ^* i" C; @3 g& h }% V7 K" _" v& p
return res;' p y$ d; e X: f' Q% L; O
}. {. A5 B0 {4 Z, \9 M7 ?7 B
; ?3 @$ O) O/ G$ `$ [
private int[] f;+ [1 @; h: f: X$ m
}8 Y z5 J8 H/ G2 m
|