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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】$ Y" \$ J, A5 J. R: p
解题思路
" s# R  \3 R5 y7 X: H# Q6 a签到题,循环判断即可。
5 L+ S' J; J0 c. J2 w/ u$ o7 k
代码展示
( v0 Y0 c7 v7 E7 s5 d) q4 K* ?+ [0 v9 j$ }- t0 `6 p. N5 D& T# O
class Solution {7 k1 ^  n- i9 x/ P5 W+ G
   public List<Integer> targetIndices(int[] nums, int target) {
' g( u, G* b2 c) z4 b       Arrays.sort(nums);
3 D( j7 p/ S9 w# E) j) n4 }" W# [       List<Integer> res = new ArrayList<>();3 S% \, M9 a+ P/ ~
       for (int i = 0; i < nums.length; i++) {
( d( G4 T. t$ @3 S+ e- f           if (nums[i] == target) {
, s3 S0 e/ C. H( R               res.add(i);
7 `4 M% b( a) R. b4 N  {          }
% e% u% y- ~" J1 Z& p: s: U6 Y      }6 h9 r. O0 i# F( f0 `; e  U
       return res;" M- H* T! Q" E/ K% C
  }( @; r; e+ |8 r7 R8 A' a* K+ \4 |
}
& q# B: ^' E' S2 J& X* L* p/ t
! q$ x9 ]8 x5 M( @【 NO.2 半径为 k 的子数组平均值】4 Z0 T$ [0 |/ s7 O& a7 e
解题思路
# n0 T( N  ^) T) I: o+ ?使用前缀和计算区间和。注意使用 long 类型以避免溢出。
/ x9 T# y5 ~$ i; A+ R1 Z0 F) Y4 G
代码展示# n5 r2 D+ q* c
9 [& {" _7 N2 I
class Solution {- }1 m( @/ g; H+ W; m
   public int[] getAverages(int[] nums, int k) {3 M( _! Q& X9 v5 j( p/ u. v# d
       if (k == 0) {; \3 x. H) u5 M" L' p* b( P9 |* ]
           return nums;0 [* ^  |4 z% v& g/ M
      }
, n  f2 i. s" q5 [  t1 A3 m       long[] preSum = new long[nums.length];
% F  e( \! Y" z+ p3 V$ ~. |* U' `& W       preSum[0] = nums[0];
# W: u( c. A2 ?" W5 s2 \* F       for (int i = 1; i < nums.length; i++) {8 D) v5 F$ M. m- @0 ]7 D: F
           preSum[i] = preSum[i - 1] + nums[i];- q) M% b5 t: Z) b, V" s9 V& A
      }
; ?' m. U4 S" y+ t0 W       int[] res = new int[nums.length];* v6 r8 l, h( d& i  J/ r
       Arrays.fill(res, -1);
9 L7 V# f3 L/ G$ W0 g# n) p, L       for (int i = k; i + k < nums.length; i++) {
% i1 j6 \4 |$ P5 d, X" F, ?           long sum = 0;
% J2 O0 v4 a5 ^9 M" t           if (i - k == 0) {4 o" s* X# n) _0 ?
               sum = preSum[i + k];
. C2 @& }, |3 l% h9 V& `# G; F: C          } else {" i: D: t# @( P" ~
               sum = preSum[i + k] - preSum[i - k - 1];  r+ [& l- _# Q4 o6 w
          }
5 E- I' o& Q1 S. L           res[i] = (int) (sum / (long) (k * 2 + 1));/ d( Y. B6 Z- O; D% I3 ]
      }% Q; m3 S' t; e' W+ P4 Z8 R/ |9 ^6 w
       return res;
8 [: l- h9 T, w; ?1 C- k* S( j  }
/ A7 f  ~0 z. u1 d}1 J( A( S& a7 S; B5 k

; P/ l4 x8 f, z9 R& y0 l【 NO.3 从数组中移除最大值和最小值】, W/ D( K5 I" [5 s- T; Y
7 c+ C- L& k$ Y3 j# V
解题思路* F; r: z5 l2 N: j* k* J, C
贪心,按照最小的花费移除即可。详见注释。
0 g9 p8 E1 s& X% W; ?8 W! K
, ^, X8 v. u5 b: Q# I& B代码展示
% N" _/ Q6 L+ \0 q/ }
' e5 G! k, B% f  {! M/ Wclass Solution {
4 E: e% X2 k3 y5 K( c, K   public int minimumDeletions(int[] nums) {0 \! G7 Y7 N$ R3 `, K# d
       if (nums.length <= 2) {
  K- D* Q! E! v( ^" m1 K           return nums.length;
4 _, q# |& v1 g  ?      }
+ j6 M, b5 Q$ K& j* R       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
$ d, N: p* k+ U4 [5 P7 j       int min = 0, max = 0;
4 F: E3 s2 \( U: k* g3 x/ i       for (int i = 1; i < nums.length; i++) {: d- l/ v. \2 F
           if (nums[i] < nums[min]) {
6 _3 @& ?! P) r, x2 o: D5 d               min = i;8 h" T4 g6 d$ i* D( f
          }
8 j. t+ L  g' m8 h           if (nums[i] > nums[max]) {! X# y4 v1 n8 y' F6 T
               max = i;
/ S% o+ M5 r3 Q: ]! |          }
! n+ C+ d% m% G8 I- t      }
3 Y7 n* M; a8 S& |0 n       // 要移除的元素下标为 max 和 min- ?7 h8 o3 s+ H" J2 K# b% O
       // 此时我们只关心下标,谁是最大值谁是最小值不重要' r0 ?0 w6 \9 P! X5 a' w/ K
       // 为了方便处理,令 min 为较小的下标
( W# f5 x# r( H+ R7 \       if (min > max) {
# i7 x( G  N  T8 j9 ]% V8 H# ^9 S           int t = min;' t' J9 O( k. b9 z- Q8 Q  x" `6 [
           min = max;
/ n0 l7 g' w6 M$ S# S; a5 w! m           max = t;" D/ v" u& N( @, o5 c, Z
      }
. M: W! r; Y; h* t       int res = 0;
; c" o" F9 _8 E3 w& D6 M( c2 V       int left = 0, right = nums.length - 1;
9 b/ ?+ G' G' E& F1 b& S0 ^       if (min - left + 1 < right - max + 1) {% Y5 H$ O/ o$ W9 ~( m' B
           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min/ h6 R8 d0 X' T: K* C
           left = min + 1;8 H* @. u" O$ J4 c) P' [9 h
           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max* k3 m* ~) e1 [7 ^( v
      } else {/ H- A) k- I: E3 t0 @
           res += right - max + 1;
# r5 g# k0 @  u! ^           right = max - 1;
6 b* S- v# ?! u$ \! q' }, i           res += Math.min(min - left + 1, right - min + 1);
- m) {5 u$ y3 n* Q0 a
/ @& k/ b! b. a' [. y! W8 ^& F+ q" p      }
0 P* _3 H1 {; [  j       return res;
& s/ V- E/ ^; J. K' P: }. g* R, \  }6 w" F! u2 ~- w$ C
}" X1 i7 ?9 b0 R, T0 _
; t9 N2 X& \8 q9 a
【 NO.4 找出知晓秘密的所有专家】
$ i- P. L$ v+ k
1 h! `$ t4 a; }! o" k; |+ H# L解题思路
; f* F0 b+ k( z9 x8 L" Z/ v7 R并查集,详见注释。+ o4 B0 G, r6 C) @. e7 x( {
& m% C) T4 K0 e: m! S
代码展示
' \& p9 @8 s( g$ [7 n3 P7 [& g3 P4 i
class Solution {# u9 b8 N$ r$ q6 |9 i. _, r% W
   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {  `% z- y! U) G& s/ n/ z" T* L+ i
       // 按照时间点将会议分组1 F3 `- v' `" u* A3 J
       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
, \' n1 g3 s) v. C, e; w       for (var m : meetings) {
1 y1 J& f. \* h& r& e! b           if (!orderedMeetings.containsKey(m[2])) {) k: O. k" F$ d. V! J0 h2 y" t
               orderedMeetings.put(m[2], new ArrayList<>());; p* z8 d* ^+ y. w$ G* E  e
          }7 R! }8 b: P+ w3 P. n
           orderedMeetings.get(m[2]).add(m);
+ v, H. O! o& `5 p( ^      }9 K2 y3 u9 N7 I* I
       boolean[] known = new boolean[n];
* G% Q# t' l, F: n       known[0] = known[firstPerson] = true;
" T9 y0 x( ?. H) I8 b/ A$ J2 Q, D       while (!orderedMeetings.isEmpty()) {3 Z( b/ D' q; L
           // 按照时间顺序处理每一波会议' \+ j9 o) `( r/ F5 C& f5 X
           var entry = orderedMeetings.pollFirstEntry();
. v' @4 k/ j! n( S: Y           var curMeetings = entry.getValue();
3 c2 ]2 w& w. b4 k           // 使用并查集维护当前时间点发生的所有会议中,有关联的人: d- a+ ?8 L% ^( P4 H6 e  g
           UnionFind uf = new UnionFind(n);
; R$ ?3 \4 W- J1 \& {0 `/ Y           for (var m : curMeetings) {( K. g* y, J$ U. I8 B) G3 z
               uf.merge(m[0], m[1]);; N8 Z' X1 C. m+ Q, Y0 \% `0 p% K4 c
          }- U5 i; p! V4 Y$ x3 }; @, Y
           // 枚举所有会议0 X' W- C$ Y# s2 r, j
           // 若会议参加人 m[0] 或 m[1] 知晓秘密. b. |4 L5 D6 }' ?" W3 {: V
           // 则把他们所在的根节点也标记为知晓秘密
* ?$ U, z- w; ]: z4 p" t6 k           for (var m : curMeetings) {
+ V( H2 W% h- _; O, Q$ [& w' n               if (known[m[0]] || known[m[1]]) {/ r5 O7 ?2 D  [% z9 i
                   known[uf.find(m[0])] = true;; u/ \/ |% q" G0 i9 o* f
                   known[uf.find(m[1])] = true;7 R3 d2 f% x% M/ w! h, Y
              }  N- {& \( B1 c8 d
          }
, O" J# v# l$ Q  L5 P8 \           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密/ r. @8 ~8 n) d- {3 ~
           for (var m : curMeetings) {0 [3 u" m+ z+ ^* m, V
               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
: i9 l5 e9 J) {+ |% _                   known[m[0]] = true;
1 S3 s  c% I1 V- K, \6 ~. U) k                   known[m[1]] = true;( H4 H' }7 ?* f7 X1 n
              }
7 E$ z# C! {" T1 ^          }
5 ^) V: b' b' ?7 }      }) P# s7 ^; x7 d; d5 X( m" ?
       List<Integer> res = new ArrayList<>();) b% x. ^" L) S; m1 Y" d% r4 E
       for (int i = 0; i < n; i++) {# g" ?5 N- d0 {- t) U
           if (known[i]) {
$ N1 v% U! D* I) l& Z               res.add(i);: ?$ Z. r" |: @7 [4 _. q9 j
          }5 ^! Z( C$ V4 W9 h7 v! {. `; g  W
      }
# b0 g/ I/ w( R  z! _" Z: y. t       return res;) u' V" i$ F* E" K, Y; Z
  }
. X7 Z9 f4 r! W. _- W( k6 I- q* J0 s}
' _4 ^, r) F) t
- B3 Q: J+ `, ?" qclass UnionFind {; _# m0 {  ^! }& x* ^3 r2 S! [# V
   public UnionFind(int size) {# j* `+ ]* N$ K& Z
       f = new int[size];9 U: A9 h9 ~7 a3 U, R
       Arrays.fill(f, -1);4 a" a, J% l, w! T7 h! X
  }8 S4 ?& K% d' c) {3 S
( J0 ?  N& b% u; r. N3 N" }
   public int find(int x) {9 N4 }3 k0 }" M. h* j* b% C
       if (f[x] < 0)1 C! E; j  r5 _8 p
           return x;7 L+ g( N5 L$ M
       return f[x] = find(f[x]);4 H5 Y! h2 s8 \/ s# c  V0 o% }2 o0 ~
  }4 ?3 r" W0 @! A% P9 k  {; l) z) N5 L
2 c5 m, ~  T4 V7 ~/ H
   public boolean merge(int a, int b) {
' i' E: ?- K6 J- A3 k       int fa = find(a);
6 k1 d* N) F+ r$ y" Y/ x       int fb = find(b);
/ @( I8 R' i) \  o- y9 u2 G3 E       if (fa == fb); [# A: m  Z- a0 d. _  ~# N0 N2 y
           return false;' \0 i6 ^3 D5 y* g
       f[fa] = fb;
" E! g( U  }$ w+ E+ }& M' e0 X0 r       return true;! M' s; r! |: }/ k8 U9 O
  }7 t6 \; k2 U# D4 B5 D* \- N1 m5 B

7 O6 `/ I  O! K: J) y3 e! M   public Map<Integer, List<Integer>> sets() {
; ?% r) A7 y4 m       Map<Integer, List<Integer>> res = new HashMap<>();
! ~6 Z9 _& b( X       for (int i = 0; i < f.length; i++) {, E( ^5 Z  n, E. r9 c' |
           int fi = find(i);1 t! m/ @7 m; Q2 Q( R2 P& ?
           if (!res.containsKey(fi)) {5 f$ D# y+ ^: B
               res.put(fi, new ArrayList<>());5 ^* Z1 B1 `7 @0 K# E) d' z
          }
. U$ w4 g# v8 e( h9 S           res.get(fi).add(i);5 ]& I- T# W7 F6 {  t
      }5 {3 k# a+ t1 N0 N* e
       return res;
9 o8 W! d4 n, g7 o/ U! {4 l) ]  }
7 l* d! `# ?( R% r8 Z6 h" i& U) a7 f. e
   private int[] f;7 J* u1 J& x5 E3 K9 y
}
7 X8 j3 G! m3 J
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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