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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】
6 ^+ H1 V# d6 h. T1 _7 y解题思路* W, X" p0 i1 L8 ~5 Z2 p- z
签到题,循环判断即可。! n* T3 Y4 e, q& \6 L' [2 H- _

. ?/ X& R  }2 U6 H+ h* P代码展示/ l9 ]+ }4 J' ?& j' @
5 Q: x0 p( E( `' q
class Solution {
+ h9 f) f8 `6 E; V6 E/ W" y   public List<Integer> targetIndices(int[] nums, int target) {# x8 E- _5 ?6 ?
       Arrays.sort(nums);, i8 r9 L' p3 [" h. O- C9 K
       List<Integer> res = new ArrayList<>();- x& ~, c, N) m0 c# {
       for (int i = 0; i < nums.length; i++) {
1 D5 f6 K9 `1 Q" T           if (nums[i] == target) {
+ @& }+ t7 {, r) V( k& E               res.add(i);0 `0 Y% W- P& [/ k, r
          }
. p( @# o* K; z) X) ~" h+ K      }
1 y6 w4 X" v1 ]8 s       return res;3 z( @& a( \+ t/ d( h( u" p
  }
0 t# }, `" \3 q# w}% B5 s' p+ [3 A% ?

$ C* y, p& g9 W8 V/ |9 P【 NO.2 半径为 k 的子数组平均值】
" o2 Q; D8 n  Q; \+ X1 S! A4 ~解题思路7 ~/ a: n/ O0 w! U# r7 L
使用前缀和计算区间和。注意使用 long 类型以避免溢出。: P- V) ^! z  q& R  L8 `$ ?7 T. p

' o& p. [7 a) j  L# r代码展示2 K2 o- q5 P: _, W( w1 G
$ ], u! c/ a8 f1 U4 q9 B9 V  p
class Solution {+ b' A: r  i5 R* A0 S
   public int[] getAverages(int[] nums, int k) {
2 u8 c# B/ x& c! Y       if (k == 0) {: V2 \0 j0 y. I, s4 m) |
           return nums;
* Z- z- {) h5 {0 w- {      }! F- j2 h7 K/ C" L! W6 j6 U2 ^
       long[] preSum = new long[nums.length];2 X3 L% ^- U3 x+ G  r( }
       preSum[0] = nums[0];1 S( M# F. E9 h7 k4 z( {; Z
       for (int i = 1; i < nums.length; i++) {
, X$ F+ N* R: `: E           preSum[i] = preSum[i - 1] + nums[i];6 j3 w7 ~  ?5 D# I( ^8 g
      }% U3 f7 g1 |. J* l6 Y; d  T8 l
       int[] res = new int[nums.length];
" l2 q3 ?2 U9 ~) M! z9 E       Arrays.fill(res, -1);
9 m+ u1 P3 u1 m( Q7 D! C& v       for (int i = k; i + k < nums.length; i++) {9 E1 {& Q6 s6 e) d
           long sum = 0;
# S2 e/ t( h/ Z1 W           if (i - k == 0) {/ O  f0 }# w, N/ e' G9 C0 t9 i
               sum = preSum[i + k];
* a3 P, l* B  S6 l, ~$ u          } else {
( t( V5 _" l. \1 Z/ p6 I               sum = preSum[i + k] - preSum[i - k - 1];% M- e; R* B( S9 T
          }" P+ K6 R/ s( T1 {! O- P* @
           res[i] = (int) (sum / (long) (k * 2 + 1));' ~5 K3 U" M7 a; x  S" ^3 e
      }- L* ^: m) [; v6 x! h
       return res;
8 N2 M  w( i" t9 T- C/ F  }$ C1 ?  {2 k* u  [. e
}
* Z+ n) i' Z, E- {  G$ `5 U9 Q' K# S4 K* W6 W' w# y
【 NO.3 从数组中移除最大值和最小值】
$ h) q# g; H5 W
1 {  P& J- ~: Y: f解题思路
8 }0 L" q9 h% A; m6 t贪心,按照最小的花费移除即可。详见注释。
2 j8 j% e9 t! O  J2 e; w& {" O7 o1 r4 f7 g6 I7 g* z+ K# q: Y7 i
代码展示) l& E: q  u0 ~* \
" ^! S& ~9 Z9 b2 {
class Solution {
4 f# ?; L/ n# c1 r% R   public int minimumDeletions(int[] nums) {' v, r: J* T& P2 ^1 V# E
       if (nums.length <= 2) {: n# J5 k# H) u+ l8 U" p/ V
           return nums.length;" l4 o# L! H# j* F
      }) H) f1 ]* |) B* q6 y1 [2 g
       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min! T( ~6 K- Y8 _* F) W
       int min = 0, max = 0;3 n: V. Z# d  l
       for (int i = 1; i < nums.length; i++) {
2 k9 P4 @2 \! B0 r$ Z. |2 Y           if (nums[i] < nums[min]) {8 {7 b" F% y- p( _( w4 G
               min = i;
* y& `/ s* p7 ]          }
, `% \  f3 n! }           if (nums[i] > nums[max]) {
1 k- k$ e2 I. n; r9 X               max = i;, H( }, \0 O2 m) f# `
          }
: X8 B- p! l5 Y0 I' u5 t      }! ]* j" k; B  U
       // 要移除的元素下标为 max 和 min3 x+ ?# s# Q! P% D) G
       // 此时我们只关心下标,谁是最大值谁是最小值不重要) i. p3 f' q* p
       // 为了方便处理,令 min 为较小的下标6 a, \7 Z2 P) |: P! N$ g. T
       if (min > max) {- `7 V; H. a, w% o' W& z
           int t = min;1 L1 f* p) r' @( o& P
           min = max;& @8 A# y1 g  ~- C' z
           max = t;2 }, F+ m' ]& T, `4 O, N
      }9 k! F. |8 H2 L6 W. r
       int res = 0;
: Y/ n  N2 o  Z$ O1 f       int left = 0, right = nums.length - 1;
' D! e0 q7 r, ~; a7 S/ d, n* }) ?- ^       if (min - left + 1 < right - max + 1) {
' J: J, b- \+ g; ^+ A           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min7 X, `( g% }1 G) d6 v4 S: L
           left = min + 1;
- j$ ~6 ~! |9 m           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max  }" Z7 d3 n) o* r% u
      } else {3 g; `; Q& D5 E- o+ Z
           res += right - max + 1;: h( E0 A; ?. C* w: r. f" l5 `
           right = max - 1;
2 c0 a# T" j6 s- X" S+ P           res += Math.min(min - left + 1, right - min + 1);" H- e" O& b4 @3 i  p. e) ]
* [" M* n0 h: b- G
      }' k- a1 E8 K8 `7 ~
       return res;8 `( `' Q  S/ t$ Q0 X8 a: J
  }. P# e. A' ~: a6 S
}
$ p2 w( R1 q3 h5 J
7 _$ D0 @3 Q. q* ^3 [# R【 NO.4 找出知晓秘密的所有专家】. `8 x# @# E# g: ~  F: b

. w+ ]1 o1 \) i解题思路
/ J4 j$ h( N7 y, f8 s. [7 w并查集,详见注释。
; U; M! V) g" {- ?, d
$ |6 p; V* T: Z8 P' z+ J$ v2 f代码展示9 O' L4 M+ P& K

8 H' ~, o: i* M% K% Qclass Solution {
2 L9 v$ D, D4 U/ E   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
% W+ f% t0 y' X       // 按照时间点将会议分组
# q6 p9 U* A0 \3 h  R4 B& a       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();7 _% p, ~+ \; `; D- l# U; A
       for (var m : meetings) {$ ^# Z/ t& m/ C7 S
           if (!orderedMeetings.containsKey(m[2])) {
1 f. G' R1 @0 H' m! I7 P  d/ J( j               orderedMeetings.put(m[2], new ArrayList<>());) |6 [! t3 E4 e" r
          }
* c* c6 \) k( z           orderedMeetings.get(m[2]).add(m);8 K$ O4 \+ i% W4 Y
      }+ A4 I- e5 l) d1 G+ v. w
       boolean[] known = new boolean[n];3 u8 h8 U" f1 Z
       known[0] = known[firstPerson] = true;  y6 J# e. Q  y) E4 i
       while (!orderedMeetings.isEmpty()) {
2 {, _  K; _; j1 ^6 ~. z) v' D           // 按照时间顺序处理每一波会议
5 f5 _7 m1 s& \# `. x% d' ?- H7 @           var entry = orderedMeetings.pollFirstEntry();" B" M- k) _: ]7 f$ X2 R
           var curMeetings = entry.getValue();' B1 m1 i1 k' J. X6 T! x
           // 使用并查集维护当前时间点发生的所有会议中,有关联的人
3 L4 m7 q2 `5 h6 v& b  i6 _$ _           UnionFind uf = new UnionFind(n);
# a$ x% w) _" x) f2 \$ g. x           for (var m : curMeetings) {4 L, o. b& S* ]: y8 i% A" E
               uf.merge(m[0], m[1]);$ k0 }" e  u: J
          }
! Z6 R2 n2 N  {) u% o( ?: z           // 枚举所有会议
6 j6 X. e; n) S9 n. a           // 若会议参加人 m[0] 或 m[1] 知晓秘密
) i0 n; }' D( d; D- r8 ?! v           // 则把他们所在的根节点也标记为知晓秘密
& a- Y0 W; z8 t! Q           for (var m : curMeetings) {: C8 r+ R" i, t6 p8 ?: d3 _. e2 T9 ^
               if (known[m[0]] || known[m[1]]) {) k$ r! M: F: T' i& c. z
                   known[uf.find(m[0])] = true;% a7 }+ t! g& g( A7 P
                   known[uf.find(m[1])] = true;
$ P% m# G" n- J* P2 i! v5 s              }
5 a! `2 w! s1 u7 |3 k6 l          }6 ]' y2 H: M0 L
           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密( U  P3 v  e$ W5 X2 ^2 D
           for (var m : curMeetings) {, W( _, _% o; a& ?6 K
               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {+ F0 k# Y7 o( m8 R5 a* ~  s  H7 g2 C
                   known[m[0]] = true;! Y  Z8 R' P0 a! V, v# I. o% |5 H" r
                   known[m[1]] = true;( ]9 R  k+ [9 o' g
              }
% ~- Y2 g  j$ y4 e1 t- ]          }
- j" ~1 U+ D$ e      }5 r# l# M2 D# |
       List<Integer> res = new ArrayList<>();$ @* E4 j' x3 U
       for (int i = 0; i < n; i++) {" B% k' W9 y# C+ s9 Q3 @5 g
           if (known[i]) {+ F5 L( E0 q4 }5 L" Q: {
               res.add(i);
% O; ^/ ]# x5 w4 S( M+ R- F5 k7 x          }" g1 _  k* [1 v8 y  V. K8 Z
      }
3 {8 A. b& l7 y' ~, q       return res;
* V: T- p- S8 P  }
. C; _% V" P3 n}
) s2 D& w0 E2 ]2 i
! l; s- T& x: ~1 c) K* O5 @class UnionFind {0 i0 X; H: o* Z& J- R
   public UnionFind(int size) {1 y# a: p) q* i4 e1 Y# ]# q
       f = new int[size];
! W4 Z- ]7 _, K) q( l       Arrays.fill(f, -1);
) w4 G/ H4 n; g% ?" w2 t- ?6 w  }
1 q+ s$ ~5 z- E8 t
/ \7 ^1 h- @( |" t. o0 _4 j1 Y, U4 f5 ~7 L   public int find(int x) {& y, @3 y- _: k, y, K% I+ x* X
       if (f[x] < 0)
, ?, j6 G3 V8 G  x( v+ _4 n$ \( Y1 E           return x;
0 Y  o9 B6 _8 g1 k4 j       return f[x] = find(f[x]);+ y1 T2 x" d" G) I7 o
  }
/ g$ w% A. f5 R7 B$ ^- p5 |5 g- U# ]9 ^3 p
   public boolean merge(int a, int b) {
% R+ q! _2 M* f: J7 A       int fa = find(a);2 L0 r" |5 h4 `6 ]+ Z
       int fb = find(b);
; }7 E' O( j9 Z5 x       if (fa == fb); n) X% A  r, h# P" k4 M, W4 y$ ?
           return false;$ P7 {6 Z% F- u% A8 F, r0 T
       f[fa] = fb;
4 y, W* r% z5 W; v* N" N0 q       return true;
7 x# C& H8 A* s: i- z& `/ x  }
# P& J! s2 m* v0 J( m( \1 R- t1 r: n+ ~% O1 I
   public Map<Integer, List<Integer>> sets() {$ ^1 e" L0 ]& y$ U; F# ~
       Map<Integer, List<Integer>> res = new HashMap<>();
& x) ?3 P  K1 d7 p       for (int i = 0; i < f.length; i++) {0 U7 ^: \( a9 `2 Y) Y* j0 d
           int fi = find(i);7 p! v. E0 `$ ?* P9 O3 u
           if (!res.containsKey(fi)) {
! ?* \" L2 c+ v, ]# A               res.put(fi, new ArrayList<>());/ e3 n8 E0 M# H0 V, F" A: M) N
          }
3 q3 `+ y& \9 `& K) ]; E0 @& M           res.get(fi).add(i);4 z0 [* k7 H4 J3 {. \! A' D
      }
5 P+ [; d- P; x       return res;# i, y6 \. E6 A+ c1 p
  }
+ [$ e8 y1 e) l: X9 h
: r) Z/ [- q0 D. V+ H5 l   private int[] f;4 E  q" u( j! `, [( R3 U$ i( H
}
1 u2 z2 {* b2 A
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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