找回密码
 注册账号
置顶:如何加入2024届新生微信群

[吹水聊天] 上岸算法LeetCode Weekly Contest 269解题报告

上岸算法 回复:0 | 查看:2916 | 发表于 2021-11-28 19:33:10 |阅读模式 |复制链接

UWCSSA提醒您:

警惕网络诈骗与盗号,不要在他人发送的网站中输入密码,换汇或付款时请小心诈骗。

为了避免个人信息泄漏,建议在帖子中使用不常用的邮箱,或使用私信发送联系方式(点击对方的头像,然后“发送消息”)。

帖子通过审核只代表内容不违规,CSSA 不会验证内容的真实性。请谨防诈骗。

登录后可回复主题

您需要 登录 才可以下载或查看,没有帐号?注册账号

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
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

登录 发布 快速回复 返回顶部 返回列表