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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】
1 p+ c* B4 T  W$ z解题思路7 ~+ ?9 j, L) v
签到题,循环判断即可。
" o. W: i3 o! _" P2 q$ M9 G0 a+ Q9 K2 M0 V& S
代码展示
* M* P+ j- w1 a5 C
% b3 K  b* i# O3 ]class Solution {
! v% V( n3 x+ ^5 J! _2 a   public List<Integer> targetIndices(int[] nums, int target) {
1 a" `# w9 z& e5 W2 K       Arrays.sort(nums);3 o. Q! {) U! a' ]3 d
       List<Integer> res = new ArrayList<>();
# E) ^& ?* x$ I       for (int i = 0; i < nums.length; i++) {" F9 `; v9 U( W5 A5 e6 b
           if (nums[i] == target) {" `5 E# E7 v2 x; W! K& ]# u, E
               res.add(i);% z6 [1 X9 A0 W( V4 H
          }2 V. F) d. W3 o7 q
      }7 t! t4 G" t" D" I
       return res;
" g  o. z( G2 `5 d  E3 a; e  }
0 _8 K! {; W0 C/ ?( N  Q3 M}4 y2 w2 J, W6 |. Y' k

1 |3 T' j% o: K9 `1 i【 NO.2 半径为 k 的子数组平均值】
3 n* Y3 S* U& l9 U4 I解题思路
5 {" J3 b+ R9 Q2 S+ M使用前缀和计算区间和。注意使用 long 类型以避免溢出。
/ J) X/ m* X3 e8 c% D2 k1 `) _3 V6 y: x4 g% D
代码展示. f$ ?# |4 I2 C, P

; ?- w- W; D; xclass Solution {
2 [* {1 }: Y+ E, M& V; P) V5 w4 X( H   public int[] getAverages(int[] nums, int k) {
; f$ b3 I3 ^& [; H3 i* Z       if (k == 0) {
' G: J: l; o" U# a           return nums;
, f% W* e+ U  Z3 j5 ~% T: y2 E      }
0 [! x  A* z, g/ S$ h       long[] preSum = new long[nums.length];
3 e8 x" a% {: i3 z! i       preSum[0] = nums[0];; |" h; W  s: [8 ~" p) H( a
       for (int i = 1; i < nums.length; i++) {) ?  K0 n0 w3 j5 e: K2 _
           preSum[i] = preSum[i - 1] + nums[i];3 y8 f: H( }( D: q5 X
      }
1 G$ s3 W/ ^2 K- b       int[] res = new int[nums.length];
+ Q" S2 q6 F- M0 g. W       Arrays.fill(res, -1);3 R& X6 {) Z3 o- r1 D
       for (int i = k; i + k < nums.length; i++) {; C' A$ t9 w, Q" F9 v! n
           long sum = 0;! e; x% H8 }8 k! E/ O$ U. `; G
           if (i - k == 0) {
8 X8 k- s/ S. v6 [6 H' ~/ y, v5 C               sum = preSum[i + k];
; g  N0 n6 R# f' z+ p( i0 x          } else {
: p) ]! R3 @; I( N% o9 T1 T               sum = preSum[i + k] - preSum[i - k - 1];
, [& t4 I7 k% Q. y/ a          }
+ c) K+ N6 n3 z1 }6 I+ z/ g% g           res[i] = (int) (sum / (long) (k * 2 + 1));
  `' |/ d9 b& O7 e0 r6 K3 c      }5 U  N  B( c2 Z+ g* ~3 V. d! \# h
       return res;3 r- w9 x/ M2 d2 ~4 s. K
  }! M# f8 M; D) @$ g$ B$ N: u# o
}: w) S2 D. J' m, Z1 z- y! e

, A0 ]7 ^! B' ^; ^9 j: C- P6 _【 NO.3 从数组中移除最大值和最小值】
4 N3 b7 z. Y; O% H9 \# f7 z
" u+ y* K0 S) D3 J; `解题思路; J6 V( F$ t/ w: f: u
贪心,按照最小的花费移除即可。详见注释。& s5 V, X) Q- S- Z1 k

* {7 {  W! o5 m& ]7 i& f代码展示7 o. P8 H$ ^/ R2 @1 d+ V
! `5 W! y6 C; w" i
class Solution {' i& g+ q1 `7 p+ o- N7 `+ N) W/ ]
   public int minimumDeletions(int[] nums) {* ?' A8 a: s" I2 I
       if (nums.length <= 2) {& ~, ^- n' }# n& b6 \7 j
           return nums.length;- M/ a7 I, M" T, z* N/ R7 L& P, ~( S
      }
& r& ^. X* f  j6 Y       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min4 S4 y/ u+ `# i" S/ Y3 \9 H) `! [0 [/ g
       int min = 0, max = 0;- ^  d  q4 y! l) w; p
       for (int i = 1; i < nums.length; i++) {
4 S  C  R/ {; m) w: V3 b4 j$ X) w; a           if (nums[i] < nums[min]) {
+ ]. w9 X: K) {! w5 ]               min = i;
% V1 h: }6 P2 T; _' F2 _  l& x& i4 A9 H          }
; r. w) M1 L. u7 D           if (nums[i] > nums[max]) {
2 a$ X8 d8 r0 U! c) Y               max = i;
) ^5 G- V, Z; ?5 o( S1 Y- ?9 C          }' r$ t& h) ^/ l
      }# I4 F. A( q" _0 L. Z* j$ I
       // 要移除的元素下标为 max 和 min
% \$ o9 D' z% \' p* x' j' _( O/ V! r       // 此时我们只关心下标,谁是最大值谁是最小值不重要
) u# T, r2 U/ ~5 q, O9 R       // 为了方便处理,令 min 为较小的下标$ N4 b: S9 i$ x: Q
       if (min > max) {( C% s$ d% ]! b
           int t = min;
/ V1 ~. P- }1 R. H( |           min = max;1 @* m& H# I$ n; M0 G* Z& ]& e4 q
           max = t;
. f: r% l. h* e0 p& ^3 M      }2 S6 J7 x: x3 S
       int res = 0;
2 `6 Z8 H% W- ], U7 n       int left = 0, right = nums.length - 1;
' V- _, i" N" {  j, H& q       if (min - left + 1 < right - max + 1) {
* M& k/ s2 [. B: y+ F           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min
# V+ U: D* L, y+ Z/ X5 i8 T           left = min + 1;
* _4 }  H$ M5 q! {3 u           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max. k& G8 {& @$ K1 ]% g
      } else {
6 T# n$ m& b( A, T! j           res += right - max + 1;$ E: h, C3 I; @  v1 \. |1 O$ ~
           right = max - 1;3 X! \( |, i! \- O5 _) `- P4 Q
           res += Math.min(min - left + 1, right - min + 1);
$ L' ~( A- ^: L( y7 `% ]8 p9 o% }0 M- N# [
      }( T3 ^$ T) f) l% u1 X! X9 _
       return res;
+ ?# w9 I0 n8 D' z8 _6 e  }
8 U( H7 c+ X% |0 N}
5 K6 U* N2 `( {  O7 ~6 x/ n% i  H2 `: q" k: J
【 NO.4 找出知晓秘密的所有专家】$ O! Z" Q  t! m* ]1 o

3 _+ P6 `7 f# U4 ^7 D解题思路; E  N/ `3 s( k8 M/ V; T) b
并查集,详见注释。: H/ \2 P" O: b& T

6 O2 m! r/ r9 Y+ D代码展示
! ?$ c, ^# d% A6 n- D4 b) }3 G7 I: L7 T, U  L4 Z0 I
class Solution {
/ S% Y) P3 g! k( b0 ^& R- [   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {) a& z! e4 _' d0 E2 E2 b
       // 按照时间点将会议分组
1 N4 S; J( S1 S! W       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
- b" [* x- t1 }% K1 [6 G5 i  U       for (var m : meetings) {6 T5 K  p/ B* V( Z; u2 E2 V5 m+ a2 i
           if (!orderedMeetings.containsKey(m[2])) {
# o/ @: h% s: D( Y8 \7 h               orderedMeetings.put(m[2], new ArrayList<>());" w8 P. T+ S9 J4 a  z' b
          }) y( F! |5 M( a3 H
           orderedMeetings.get(m[2]).add(m);
" z) T# u9 a; a+ G& j  a& i      }
( \0 a6 V0 l8 K5 O1 B5 l9 ]4 P       boolean[] known = new boolean[n];! }* l4 h; j; Q: _$ @; E) |& C
       known[0] = known[firstPerson] = true;
7 T% c8 G5 S( x" j0 a       while (!orderedMeetings.isEmpty()) {# p& H8 y7 A3 Q
           // 按照时间顺序处理每一波会议: x( V; `7 X0 m. v2 F0 [7 L
           var entry = orderedMeetings.pollFirstEntry();
, j/ P' w  J1 k" x& A6 d           var curMeetings = entry.getValue();3 A9 c8 F0 e' S
           // 使用并查集维护当前时间点发生的所有会议中,有关联的人
1 c8 z% n' L# \) R7 ^. p( R  `           UnionFind uf = new UnionFind(n);; P* R" n3 h" L7 w% n: c' `" x: D
           for (var m : curMeetings) {
: r$ ^$ c8 F% c& W               uf.merge(m[0], m[1]);
/ ^5 D, }( l' s4 i# \. L/ h          }
, X. `: H6 l* X$ q           // 枚举所有会议" K- q# B' e' J* F7 V6 _
           // 若会议参加人 m[0] 或 m[1] 知晓秘密
+ I- ]8 K# a1 D& g  R           // 则把他们所在的根节点也标记为知晓秘密
# Z* G- e; Y6 O5 R           for (var m : curMeetings) {
" v/ B6 P6 D* S9 t               if (known[m[0]] || known[m[1]]) {) k' c6 n$ ~0 l
                   known[uf.find(m[0])] = true;. a* D) J) Z, H1 _
                   known[uf.find(m[1])] = true;
# g: H7 g8 J0 \& `4 C2 P              }  C" ?' z! b) t8 z
          }% G9 q* h) h  n# {6 |6 f* p8 j
           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
0 o' Q# {' G( y$ T2 w7 F/ F           for (var m : curMeetings) {
* H* k+ s, G7 q" q               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {5 b! R5 H3 R  E. p1 h" e9 `$ M
                   known[m[0]] = true;. n6 z8 X0 Z5 U1 W1 p/ X0 P
                   known[m[1]] = true;6 F% H! q" x% f. j& {8 {* d- h$ R/ H& j
              }
% S. z8 t+ b0 F4 k) P1 X          }: x5 a! l4 h7 v7 X2 \5 e
      }
& C  n9 M% [" s$ o; ^: u8 `       List<Integer> res = new ArrayList<>();7 P: t' E, Y6 p1 w5 S  G9 }
       for (int i = 0; i < n; i++) {
7 p/ i# j. m. o& {$ o7 k           if (known[i]) {
' z5 O' {4 G* P) f/ W* V               res.add(i);
* f8 _* t1 Y# [8 h          }0 X9 M9 ~+ b1 j. M
      }% r1 I. z4 w% u1 W) _3 I: J  \
       return res;% B7 e' w: [& Z; ~' g
  }) a) f7 }& n7 ~/ V* j: T" [
}+ M9 F1 G( Q! r, k) v) q; ^" R
% a+ X: T$ m# a+ H: r# N9 }
class UnionFind {
1 C: G! Z' A* w1 R! M& M- a   public UnionFind(int size) {/ F/ t. A8 E/ E9 v
       f = new int[size];
, D- |% \* L- o) U7 S- r       Arrays.fill(f, -1);6 p1 r; H; i. [/ g( ]$ h) |
  }
0 G+ v6 u8 b) o0 h1 j
/ G) J. C: ~- x+ d, M   public int find(int x) {3 O/ K/ y$ J6 c& t1 E
       if (f[x] < 0)0 w; Z+ z6 j' q5 X/ k
           return x;# w( ~4 ~  E. C7 \
       return f[x] = find(f[x]);( v, E; g. p& B* d5 @" y
  }
: S) E7 J$ E8 t* R% c. a' _; A, b0 W, S
   public boolean merge(int a, int b) {/ A# z/ I7 u- u5 ~& z! ^
       int fa = find(a);* z( {5 k4 c1 @. `$ R& M
       int fb = find(b);
) t9 Y8 J! E$ N* F* I0 d* D5 n       if (fa == fb)
, G5 Q1 t8 N; W/ X           return false;5 \7 c0 F6 s* \9 t
       f[fa] = fb;
* h: m- I& V4 G  V0 N       return true;
4 Z8 m: T' @' b* R% ?  }
* Y9 s2 [5 [# F/ ]. @" o* f
2 ?- R+ O. p0 h$ W- Z/ y* J   public Map<Integer, List<Integer>> sets() {! B6 @' z( h( E( v  m
       Map<Integer, List<Integer>> res = new HashMap<>();
% c1 I1 [% t  Z$ h- f/ u+ T8 D0 d       for (int i = 0; i < f.length; i++) {
- u4 P& {0 q- v, C! a8 a9 A           int fi = find(i);& }+ r) y% Z- ]: r( h0 [
           if (!res.containsKey(fi)) {- L% |( E, x6 e3 N- H6 s
               res.put(fi, new ArrayList<>());: n& E% d' w+ K% p7 u
          }
; k) B5 M% ^( {% p           res.get(fi).add(i);6 l  B$ j* R* h$ {4 O9 q
      }+ f# v$ [! T% l/ p! A
       return res;& n/ e) U# {8 A# N
  }
& b; Y! r7 x' B0 v9 f  ~* v+ d  w$ }" D4 d2 ]$ T1 d9 W# i
   private int[] f;
4 g) w+ L% U* R$ u( t& h- {7 X# M4 {}9 u& n* ^# b* w- r! r: m# A
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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