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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】$ L1 ?: r; |) \7 h5 h
解题思路- m) W7 w7 L: w2 o$ w
签到题,循环判断即可。
: a" ?# G$ R5 o3 Y: G& N8 |( O& j) A4 b' |2 i
代码展示3 _4 r/ d3 Q+ R/ t) h% ?
* x" [' I* S$ {6 b8 B& ?
class Solution {
6 R& V# O3 c! ~, L3 ^   public List<Integer> targetIndices(int[] nums, int target) {' w4 k; j  L" K5 M' q# Y9 P
       Arrays.sort(nums);
& l7 J; r5 a! C( [  h       List<Integer> res = new ArrayList<>();
& j8 w4 b, N3 w3 L  ^9 }% R4 m$ f       for (int i = 0; i < nums.length; i++) {9 l3 `$ Y- a) x# h6 z/ e, d
           if (nums[i] == target) {
* s) F9 x7 ?  u) T" ]; b               res.add(i);! r) G+ R8 j' |3 [4 T" S
          }
0 E: e3 u8 _5 O$ F      }* g: L3 P6 p0 A& S& J6 u* ?
       return res;
) \* H: B! c+ c  }7 e6 _% G' R4 B8 i. j. R7 Q- I
}; L/ T- F0 S( N1 w
& D4 K9 i5 d# E5 U  G) L$ K7 s
【 NO.2 半径为 k 的子数组平均值】
/ P1 ^1 @, f/ G解题思路0 H7 I* U. z1 Q5 i) s! w0 i
使用前缀和计算区间和。注意使用 long 类型以避免溢出。% b  C! F& C, }3 b5 [

9 g4 }1 Z. h7 a代码展示, K+ }" E$ u3 _5 N, q0 P# {, N
+ z% y6 m) M( X! d1 O
class Solution {( R% ^( ~: ~$ W2 r+ k8 F7 h' v+ O
   public int[] getAverages(int[] nums, int k) {2 Z, U' _4 W! \1 V' I  l
       if (k == 0) {1 r+ j  A, R( `9 N# U0 |8 c% v
           return nums;- }2 t; v- M1 @$ M) |0 c
      }
  L! J: s3 I' i, w0 \# P3 ?) ?       long[] preSum = new long[nums.length];5 t5 z* Z& J% S8 k5 g, J0 ]5 v) l
       preSum[0] = nums[0];
9 h6 x4 f6 G/ W4 i& I- M7 C. v$ U# z       for (int i = 1; i < nums.length; i++) {5 G$ y9 v% T3 b+ I( |: e5 y
           preSum[i] = preSum[i - 1] + nums[i];
% h& N! G/ t7 G' @, Z      }) s* n9 N, o! z# Y4 \% ^) p( x
       int[] res = new int[nums.length];' M+ _! D4 K4 ^
       Arrays.fill(res, -1);/ K" I; P% N8 J0 x, V2 v- g
       for (int i = k; i + k < nums.length; i++) {
/ }0 _. a' ?  }( a           long sum = 0;
2 V4 J( y) M/ B! P7 r' M           if (i - k == 0) {
  b1 w+ Q; ]: ?% v; H               sum = preSum[i + k];
& N/ Z4 J+ [  Z+ i# J5 N          } else {
( z& G- C  H, y3 W: _; q               sum = preSum[i + k] - preSum[i - k - 1];  K# g: Y  G2 `2 K
          }
+ W" Z+ I2 e2 q# p; X           res[i] = (int) (sum / (long) (k * 2 + 1));
; I/ f8 l! x, R: k% f      }2 A6 m( R, ?& m+ v3 R! Z! W& h6 V
       return res;
( ]* I0 [* E! B1 ?2 F  }
6 Z. G3 |4 G5 [: a- _( O( u}
4 o! F1 W+ Q$ B+ ]2 I7 J& n- v  T0 N3 `- ~
【 NO.3 从数组中移除最大值和最小值】# \+ {& B0 E% ~# [

8 b) s% \8 |2 u/ l1 b  h解题思路
: l7 s0 @/ L$ u" ]9 z+ L4 b贪心,按照最小的花费移除即可。详见注释。5 I  f( N' ?' ~, H& W' Y

, l! h0 n* I) r% K代码展示/ I5 C$ x) J* m5 r

$ j5 c/ Q& y, B; a+ v" D6 I0 {: Rclass Solution {
4 T7 {2 h7 F1 A2 S   public int minimumDeletions(int[] nums) {
4 ~' W) O" t, A; A; R( n       if (nums.length <= 2) {
6 b/ j/ ~9 W7 k           return nums.length;
: v8 x. v# S- K" {      }
( S/ F1 x' E  r# f9 x% V$ ?       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
1 I# R/ m) O6 T       int min = 0, max = 0;& h3 |( K4 C& S& a
       for (int i = 1; i < nums.length; i++) {
1 A0 p+ j! }; m           if (nums[i] < nums[min]) {: m# v8 n1 k& f! B9 c( x
               min = i;
1 R0 R: X- O. j2 E7 {0 v2 c: p+ S; A( t  p! N          }% `7 `/ R7 U- B' s! S# P4 W
           if (nums[i] > nums[max]) {' C1 i5 [  \1 g/ m
               max = i;8 v- l% j0 v. G
          }
! @0 d) J/ ], @% D3 h. @. f      }
* \# J+ x( @; G, @1 E       // 要移除的元素下标为 max 和 min4 D- `$ W) P% D2 g3 f
       // 此时我们只关心下标,谁是最大值谁是最小值不重要" F6 h, _9 [. ~5 k
       // 为了方便处理,令 min 为较小的下标
3 @0 Z: ~: B4 z+ |- m; `7 A       if (min > max) {
. a8 t: U: q* t( x           int t = min;- J# }) U5 ]$ y( t
           min = max;3 x- w* a7 y9 u6 x- q2 ~
           max = t;
. y  }' s  J3 i& E* s; r( P. i      }; |7 T' ~9 D; R* ]! ], O
       int res = 0;4 P6 S0 f# `( G& H1 {7 `
       int left = 0, right = nums.length - 1;2 M7 _: ^( S1 s- M/ P5 {
       if (min - left + 1 < right - max + 1) {
/ b$ \8 s1 C/ F7 l. o- @  A, E! c) V! H           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
0 m! E: s6 ^# d% F6 `1 l           left = min + 1;. W0 G2 k) _  K7 o4 i
           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
& j  P/ F: K# w% r) S" }) Y      } else {
. `- i3 _7 W! R' O# w/ B           res += right - max + 1;. z# o7 n; k# M% j( z- f6 Q
           right = max - 1;
- D( ^+ k. `- g5 O           res += Math.min(min - left + 1, right - min + 1);! s1 c" w1 \+ z& p2 M
! ]* Q; j/ Q8 H# x
      }; S0 n/ H0 I5 f8 M: q
       return res;, A6 Q# u' v5 K4 M" \" m
  }
4 b5 Z+ [  }- E$ O% P/ r. T4 V}( S4 N# t9 M1 u. w

- r  x* l, U; o6 x3 k1 K【 NO.4 找出知晓秘密的所有专家】- _6 i$ Q0 F8 Y$ }; r: j6 S6 o
3 x& g2 e+ o6 R4 b
解题思路& D4 w) X. ~; u
并查集,详见注释。
3 O. k7 D: ?+ S# ?2 _# H4 r# J4 }5 W# X/ R" x
代码展示1 h* P9 O; D8 W4 e6 H6 T% J
) M8 n7 b, n8 q+ |  ~
class Solution {' k4 e9 w# p+ s
   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
/ |: n" T6 T7 ^       // 按照时间点将会议分组0 F0 q" X* h0 E  C2 _' A
       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();9 ?% x1 V# b' a* D/ U
       for (var m : meetings) {" }( n# O4 e6 u
           if (!orderedMeetings.containsKey(m[2])) {
/ l# V: u+ d* y2 @+ l               orderedMeetings.put(m[2], new ArrayList<>());% @+ p% y. d, q
          }1 A7 e9 T$ r* b" w4 X
           orderedMeetings.get(m[2]).add(m);
/ A) H' H0 o! v$ T- P0 `5 B' i1 J- A      }* W; a4 o% o9 x; _" Q2 [
       boolean[] known = new boolean[n];
) }+ \# n3 f9 R5 B! W9 D! a       known[0] = known[firstPerson] = true;
6 L4 e/ k  Y8 H: |$ `       while (!orderedMeetings.isEmpty()) {7 \2 p& ?, l  ~% y* [$ |
           // 按照时间顺序处理每一波会议
2 k, r' F8 S- Y& b# n           var entry = orderedMeetings.pollFirstEntry();% Y/ Y# v, I6 y+ H; Z
           var curMeetings = entry.getValue();
; j( K- t' ~$ M* T           // 使用并查集维护当前时间点发生的所有会议中,有关联的人
. y$ X; R2 M% d           UnionFind uf = new UnionFind(n);$ M, c& G+ r( u! H2 t# v
           for (var m : curMeetings) {
! U/ e5 [0 A5 h; ?6 H               uf.merge(m[0], m[1]);# }- t4 m# \% B% l! H
          }
8 \+ g  ~( i' [           // 枚举所有会议
8 m" Y; R  c) \# `5 W' y           // 若会议参加人 m[0] 或 m[1] 知晓秘密
+ R7 M0 ?$ R  U5 y0 ?/ t0 P6 m           // 则把他们所在的根节点也标记为知晓秘密
% W( z/ v$ D6 Y2 T) Q( K           for (var m : curMeetings) {
" i3 K$ {5 s7 H' S0 \" K1 |4 A               if (known[m[0]] || known[m[1]]) {  W; h9 f; H+ B/ c7 |5 _
                   known[uf.find(m[0])] = true;/ ~* u' n9 a# \0 R
                   known[uf.find(m[1])] = true;
& v& H) T3 I$ M  ?+ P- `              }
/ W% d  p; y3 _* M" I, m5 J          }
, {0 S, g9 l0 q& T8 f0 v: C  b           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
1 H8 }+ D8 z1 J9 Z           for (var m : curMeetings) {
. d; A# G% g/ m& s: ^               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {% y3 [# x' s+ r! L! f, J: p2 _
                   known[m[0]] = true;4 D8 i: H3 B5 z8 L$ s
                   known[m[1]] = true;2 T' s+ q; P2 a5 q7 C: N, s9 O# z
              }" ~' J" J7 g/ {4 M& v
          }
# Q7 X5 t7 c  e5 s2 g3 ]      }" C) n) a* ~3 i8 v2 z- F
       List<Integer> res = new ArrayList<>();" K7 L" D* K! \' U8 d' k. e+ `
       for (int i = 0; i < n; i++) {
6 |5 z8 N3 |$ k5 b' Z( ^9 L           if (known[i]) {- D  Q0 k- I" V  O/ D4 W
               res.add(i);
! j: m: n4 v3 }4 }! r          }
8 p  D) e9 ?" n& {+ D8 ?/ M      }- U# d) x1 w$ _2 q6 E& ?
       return res;
5 |4 L" _) ]( E1 b" u: C- a  }( M% j: O3 g* {. M9 R0 R( o6 o
}
6 F8 |- h6 Y; A2 N' k
- r# M2 g4 ~- k$ Wclass UnionFind {
- n* K+ I: e( F: Q1 P, a3 c. i+ }   public UnionFind(int size) {
* ?" m, G8 ?5 H( _% H4 f       f = new int[size];$ D9 E5 ]* B4 h2 H& H% a; T
       Arrays.fill(f, -1);- |, J* ~3 I. l% [+ e2 ?! z
  }
1 e' h( Q/ H/ H( Y6 Y: U4 z
9 R* X4 K9 e3 n! N# m   public int find(int x) {6 ~* T; T, s0 r$ _" B, j  F% j
       if (f[x] < 0)6 o$ Y% x( X! t  B
           return x;
. D7 k8 c  ^* e! \2 @( \       return f[x] = find(f[x]);5 L# N+ j; q) S! W% d
  }5 k( ]5 Y- H5 U4 p

0 R! Q) g/ k) z3 S: E4 \; ]) m# }   public boolean merge(int a, int b) {
1 l0 ]+ b% ]( s       int fa = find(a);
- S2 n) t7 U8 O' a0 I       int fb = find(b);9 I0 Q7 b7 \; v9 n+ f5 M% D
       if (fa == fb)
; x+ s* |) a* ]8 Y  L& K           return false;* q3 Z! K7 c" z
       f[fa] = fb;; b' i! g- c- ^% w. ]8 e# |
       return true;
7 u5 O9 z% p: `8 N3 u$ G$ n1 [  }0 W' _! F# f# ?! X. w1 z

/ q# {; |$ G  X$ u* Y: B  I& V( C   public Map<Integer, List<Integer>> sets() {' j! r& f0 o( q9 u! b2 v5 a+ w/ y& \
       Map<Integer, List<Integer>> res = new HashMap<>();
# l( i1 f' Q/ F# A       for (int i = 0; i < f.length; i++) {8 S7 C/ c9 Y. \# A- w
           int fi = find(i);
0 P' z* L7 R  a3 Q           if (!res.containsKey(fi)) {* ~/ d3 @9 J: T
               res.put(fi, new ArrayList<>());
; z2 }$ m6 i  F& ~          }
8 u; c0 }/ V0 B' k, y+ @; K           res.get(fi).add(i);
+ U1 N  W3 c8 d/ [      }. H! @. s+ v& u0 d$ S6 V
       return res;: L0 T, a- |) X1 a$ }
  }0 ^+ B: O9 [/ T/ I; ^
0 {. ^$ W8 }. V9 s' I: l& W
   private int[] f;% {6 J$ K2 e0 B' Y
}
6 x- d* C0 Z  n9 q9 {, Q
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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