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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】% B/ V8 g  v; t8 O0 S6 b
解题思路
: d6 ^& h( i2 u" [( g) K- M* U签到题,循环判断即可。* z& s8 K$ T# P! t- O

7 p- w1 `6 E* e4 ~. p7 r0 g  @代码展示
: H3 x. w, U0 H7 O
" ^! _3 _; X8 w- uclass Solution {% o2 ]/ Y: g- K+ \" E
   public List<Integer> targetIndices(int[] nums, int target) {  E0 u: ]4 K/ n9 I# W
       Arrays.sort(nums);6 n% q9 V2 N) X1 A2 l+ L/ `+ {3 a2 g* f
       List<Integer> res = new ArrayList<>();2 |/ O, Z  Q0 a/ z; ~1 ^1 D' Z  D
       for (int i = 0; i < nums.length; i++) {
7 r* U- G* C: P9 j. `1 T           if (nums[i] == target) {$ I; [7 ~2 P7 z
               res.add(i);
; i" ]  h* {( A3 ?# M          }( A: M6 A9 B9 M! ~6 v( ]
      }& J6 S$ B1 \* L( S' ^) }! T
       return res;/ z3 [2 J3 z" Z: a
  }! o; S. o- x, N; S3 F& E
}* ?+ t# z7 c- I" v  J3 v- r  M

$ u. C1 e( Z- d: X【 NO.2 半径为 k 的子数组平均值】
$ j4 `/ W1 }* X( v. u解题思路
# l- h5 Y' H6 N使用前缀和计算区间和。注意使用 long 类型以避免溢出。/ L4 Y  F/ m- f4 Z. T$ P+ w
) k+ Y$ }% G$ S  ]: n2 ]
代码展示, m/ c2 J. B4 D8 \& d  Z' r' e

0 c0 I! C2 r+ s& I5 {class Solution {
2 h8 O0 `- w! Q9 P! h   public int[] getAverages(int[] nums, int k) {+ N# y, H# |- C& L# Y. M8 n( p
       if (k == 0) {5 @% ^! r5 U3 n" b: ~
           return nums;
. B3 R  C* i( z5 k7 ^      }
. W; |  }; q5 M       long[] preSum = new long[nums.length];4 |6 p# O* b2 ~5 [5 L. @& ]
       preSum[0] = nums[0];
( t4 \$ k* K. T7 Q1 r) C       for (int i = 1; i < nums.length; i++) {
* k5 D( \7 G& S1 p+ u           preSum[i] = preSum[i - 1] + nums[i];! n: ]! K$ p3 ^' N) J# A: U
      }
+ c+ X1 b! G* j: m       int[] res = new int[nums.length];
( p- X4 q" O+ O9 `0 X/ b       Arrays.fill(res, -1);
7 d7 j2 w3 I  O4 L: b  K       for (int i = k; i + k < nums.length; i++) {
# F' s' l% N. [# s3 \- k, T- |* s           long sum = 0;
. [3 b- p2 F7 k" J, a+ [           if (i - k == 0) {) g# k9 N' c0 a+ P. ?2 ]4 u# ]
               sum = preSum[i + k];& F1 d/ O8 I% E& p. p  Y$ z* \' z
          } else {
' l5 m" T4 M- p               sum = preSum[i + k] - preSum[i - k - 1];% i0 T  t1 l# o, B0 ]. `
          }
+ N: R* s$ _3 r/ `' X; }9 R           res[i] = (int) (sum / (long) (k * 2 + 1));% Y$ m$ y7 y5 E. s; V5 y
      }* M1 S$ y+ q! _
       return res;: y0 |: B% C, ]1 N  Z6 g
  }/ c1 M6 E" _$ ~- d2 }
}$ u5 L0 U$ B* L2 U1 |+ |. G
$ M' H9 d- Z: l
【 NO.3 从数组中移除最大值和最小值】: w) u, ^6 l  H. ?- X% A4 }$ Z( r

$ p4 {0 C% ?# R+ k* o解题思路
% P5 a: r4 C# _: p8 ?# p贪心,按照最小的花费移除即可。详见注释。
% ?* p' S8 a! Y) ~  G
7 W9 T7 o- y% F6 s3 x* p代码展示6 ]' z8 l( h8 t. F# p

! T" N" \5 t% z0 O- b. fclass Solution {
. P" K8 W$ l) T7 V1 t, A6 V4 {   public int minimumDeletions(int[] nums) {3 U8 ]5 e- j; r1 f& j9 e7 s% f
       if (nums.length <= 2) {7 ?. `; e6 Z  O) j
           return nums.length;8 s5 \! j. y8 j2 O" U1 z
      }
" \+ k+ Q' c4 O: N: K       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min" p* w# D9 j0 R! N& M2 x
       int min = 0, max = 0;. |0 a# R: F. T4 S6 m  q: P& H
       for (int i = 1; i < nums.length; i++) {
  o  p. h5 y) y. T8 Y1 Z% \           if (nums[i] < nums[min]) {
0 V$ y5 [$ b% b7 t               min = i;4 n2 d: n) a/ S& g. D5 O
          }: f9 V6 l- d) e, F
           if (nums[i] > nums[max]) {
6 @& c# n  ^/ d$ l- o! B0 L" e               max = i;0 ^4 E' X+ v. o' N7 Y! ~, L
          }6 x% w& ~5 h! l7 \4 s# X
      }: G( e9 u1 j" Y' q
       // 要移除的元素下标为 max 和 min
3 t% g5 `4 K$ k) U; c. G. S       // 此时我们只关心下标,谁是最大值谁是最小值不重要
+ _& v9 G" H. Y3 i" m2 }       // 为了方便处理,令 min 为较小的下标
* d6 v/ _. p% D/ }       if (min > max) {# M3 V- U; B& a% k6 l. _' f8 Z' n
           int t = min;- Z6 F8 k9 u; U& m/ {! b
           min = max;
- F+ l/ ~; N! n& s* G! B           max = t;. r2 H2 |' [* w! `6 O" ^3 F# `
      }
" z) |; E+ ~5 l, @8 W- q3 e+ A       int res = 0;; w% c# ^3 L6 w' G/ R
       int left = 0, right = nums.length - 1;
( B1 g2 H7 }1 G4 [! g* c3 r       if (min - left + 1 < right - max + 1) {
8 d! s8 w# Q4 b( |) U           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
/ w' g; J& g8 e* @1 n# \  C8 z9 Z2 z           left = min + 1;! n  V7 A8 V3 S6 f; X$ H
           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max7 z% C, F3 C+ {( W$ O
      } else {& x5 x/ m3 b. B; j
           res += right - max + 1;" n6 W, q% f3 R& Y5 n/ x
           right = max - 1;
4 L8 z3 A/ {7 c4 T           res += Math.min(min - left + 1, right - min + 1);
( w- s& F: w, e( A  f# n: p* y1 V+ d
! [8 l. }+ ]  p      }" e; p* H# ?- `7 I3 ?3 V3 F
       return res;
! n/ j' c7 }& l6 c, k/ p/ K  }1 V8 P2 m/ e" Y: O: k4 j
}
" q' H. r6 a4 Q5 d. Z# r! ^7 R1 R1 \6 R. J6 N- ]
【 NO.4 找出知晓秘密的所有专家】
+ n% r* M; c7 p( U8 ]( Q
& f) \( D. @! k6 R4 |: c解题思路
) D( J& b9 m$ x# h并查集,详见注释。" ~; X3 ^: G$ H
) S( G8 \) z. P1 A" S. S. {
代码展示- p# _& I/ g! q5 o% q" P% u0 o

6 x! t$ z3 }" q* T' ^class Solution {
" I; E! J& M3 k2 ^  g  v( F) s8 |   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
1 ~* y* Z0 x4 V' S% {! |       // 按照时间点将会议分组
! Z& a; Q5 p9 l( F, O  m6 }       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();  F# G& B( L: [: A5 D" \
       for (var m : meetings) {& J+ m( O' C9 C5 B+ ~$ e
           if (!orderedMeetings.containsKey(m[2])) {; s9 @* U. Q& E6 g  n4 o* K
               orderedMeetings.put(m[2], new ArrayList<>());
3 @6 u5 a: j% m          }$ }0 \% v" w& k8 i; f
           orderedMeetings.get(m[2]).add(m);% J7 }. h8 X: B' k0 P
      }% s; u7 {3 ?* d- O
       boolean[] known = new boolean[n];
2 B+ h. r% ~" f' |( X: ~0 Q+ P       known[0] = known[firstPerson] = true;( [8 d$ c% V3 y5 K. t. M0 E' m. L2 b
       while (!orderedMeetings.isEmpty()) {
0 h. R+ X# i4 p1 r' F4 i5 U           // 按照时间顺序处理每一波会议
& E; o* F$ s& _           var entry = orderedMeetings.pollFirstEntry();* ]0 l. s! r; K+ |7 j
           var curMeetings = entry.getValue();
4 D5 Q8 c- F7 V8 s& h- t% Y' g' T           // 使用并查集维护当前时间点发生的所有会议中,有关联的人! U% r* T" ?; N6 K
           UnionFind uf = new UnionFind(n);" @! H9 b" Z) c. A. c; j$ P
           for (var m : curMeetings) {8 E+ |# s% q+ L, B
               uf.merge(m[0], m[1]);
% F7 i; r. w$ R" d: Z2 I          }$ S& B* A! i, m# l: n( V$ W8 z1 X/ p
           // 枚举所有会议5 i+ E% q: Z! u" d# i  h& w
           // 若会议参加人 m[0] 或 m[1] 知晓秘密
" F" z. n& n* ~6 o$ A           // 则把他们所在的根节点也标记为知晓秘密
# t/ |7 v! J/ x1 C4 v! V' D           for (var m : curMeetings) {4 p! a" u. n: ~& `1 \5 N
               if (known[m[0]] || known[m[1]]) {+ M! g. Q3 N, {6 L1 s/ D+ V7 {
                   known[uf.find(m[0])] = true;6 v* r" p/ \, o+ U) U
                   known[uf.find(m[1])] = true;7 [# t( _" q0 Z$ w* n
              }, k$ o4 A" j- X( }
          }
6 Z# f; C5 X# W5 k           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
, }; }. P. I: U, E8 z& T2 A7 y4 n           for (var m : curMeetings) {
% A( I5 ?* ^4 z& I               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
5 z7 R1 D* p* I9 }& w3 \- g% [3 E                   known[m[0]] = true;
# J9 q( H" I2 K. v8 u                   known[m[1]] = true;, ]( z+ A' ?7 A- Y2 C3 e: q
              }' w. O- j, i9 h% [# B
          }/ A5 m/ Y; Q9 C& N  W  c. X
      }1 X' W. g0 Q" k6 F! N
       List<Integer> res = new ArrayList<>();7 R! W4 w6 _* f# H4 r$ p6 P# v
       for (int i = 0; i < n; i++) {+ Q- K$ L$ ~. n5 K* @
           if (known[i]) {: C+ a7 M6 `* S% B+ ?) p) L
               res.add(i);& v* s' A$ J* h! z. d/ n, f
          }
' Q6 j4 k$ k; q$ r; D4 N: V      }  K- E  \8 q. R
       return res;" j$ `5 h( }' `, a( y( I! ~
  }
/ E5 y, C( M. m& C0 c}
4 o2 k3 S' N! [, s% B0 ?1 V" N0 k+ u5 X6 W# n. _/ M
class UnionFind {* r( N- v8 t  z- h7 e
   public UnionFind(int size) {
  F/ H; R7 x" ^       f = new int[size];
4 B+ b' V6 P* L& Q4 s7 K5 U       Arrays.fill(f, -1);; t* N) n: w! {, M, G
  }
, J: H( Y/ e9 D5 }& _' r/ K1 X  d; u- q
   public int find(int x) {
- _4 g3 x& E( ^       if (f[x] < 0)
1 X* T! W3 v$ \5 \9 M           return x;4 O0 v8 b- \* [6 v% j& ]
       return f[x] = find(f[x]);
! l; l1 }  X" R7 _  z  K( V  }
: E# X- e: y/ D5 m& F8 S6 L6 o5 m3 U
   public boolean merge(int a, int b) {7 Z0 B/ k8 D* o3 y( j, \8 \0 `
       int fa = find(a);4 c2 |# k: E0 ]) I1 f3 K
       int fb = find(b);
2 R( z7 @$ I% C       if (fa == fb)! m- m  q" @: D" M. @
           return false;
7 d, t, V# f) q% u' u       f[fa] = fb;# i9 E8 x- O2 x
       return true;
4 @6 D( F& N3 g3 ^: X# G, Q  }
3 i4 K+ m' q% Q' R
1 ]) ?! b' X. V$ \   public Map<Integer, List<Integer>> sets() {
/ ]- F  ?. [' N       Map<Integer, List<Integer>> res = new HashMap<>();& V/ b! K! a& }
       for (int i = 0; i < f.length; i++) {
% [+ l& A0 \- y: ~  Y# w           int fi = find(i);
  V7 Z) R, X+ [1 ?, J           if (!res.containsKey(fi)) {
& B+ {3 O3 ]; N1 K& z& [& ~               res.put(fi, new ArrayList<>());% X% q9 G# w7 `0 N9 E8 B% t- l
          }% u. z9 [2 R/ x0 h9 j+ i; a+ K
           res.get(fi).add(i);
6 L. Q- n' |' z! L      }0 k; h6 w) C( Q- r! I' @0 n1 U4 U
       return res;
+ }% q* }2 T/ q3 B) N  }
& i2 x8 H. c% _# S$ {: o
1 n6 }; l) _- b# X# y0 z   private int[] f;
. h* D1 D/ t' a4 ^/ o' U6 H8 K}1 k+ V3 }; y' ]! p5 R( r$ G$ Y
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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