找回密码
 注册账号
img_loading
智能检测中
置顶:如何加入2024届新生微信群

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

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

本版积分规则

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