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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】! G* o, V" T! A+ R$ N3 _
解题思路
% Z  j: y( V( e4 V# M7 Y/ T: b签到题,循环判断即可。
0 d% R. o; G; c4 Q2 W8 A- U4 k4 J3 S' Q/ `. y% b
代码展示$ o! x2 Q0 l0 h' Y, w7 a
; Q) F* Z: C: {) q3 x. {  e
class Solution {
% u7 @* K- K) q* W' R   public List<Integer> targetIndices(int[] nums, int target) {
& p$ h# {) t7 l. f/ b6 d) B       Arrays.sort(nums);' ^  y& Z2 _  m5 a7 f
       List<Integer> res = new ArrayList<>();
9 h+ X. Y* s& n) i# M       for (int i = 0; i < nums.length; i++) {
( R$ G0 W0 E+ \8 X           if (nums[i] == target) {
5 w. s. ^+ b! k3 m. P$ L( H0 {' O: |, m7 f               res.add(i);
5 n9 S3 e. E2 f          }* J. k0 s! s' ], }1 S1 q+ f) ^& M
      }
6 }% {8 F" V" ]# y, A7 G+ a       return res;/ v7 L8 ^/ D0 D9 p- I
  }
4 U* x* k. N+ T: W}
& M2 z% q& `, @- w2 p. M
) Z0 c& ]' d* {9 H【 NO.2 半径为 k 的子数组平均值】
9 m& H. U; H. H- ?解题思路9 X, ^! e1 j1 E! R0 j
使用前缀和计算区间和。注意使用 long 类型以避免溢出。
0 \* [' D9 x0 o1 ~5 F8 S# e5 e  F; H2 X
代码展示) }2 j) y6 I" ?( v1 R
/ [! i: h1 M: @5 [7 J: r" @
class Solution {
2 F! F5 R. ]: V5 _, V. m   public int[] getAverages(int[] nums, int k) {
3 b* P% \( Q% y0 {' g* @' X4 l, ~       if (k == 0) {
8 _( w) ^  m" u; O& e3 y           return nums;3 Z/ r% Q0 ]- ?- Z* H
      }1 h- e6 s8 c) ?) c) m7 u% S1 G) M
       long[] preSum = new long[nums.length];8 A( S( m" H# ^+ K
       preSum[0] = nums[0];
& Y# f& M9 I" S: _* l. F       for (int i = 1; i < nums.length; i++) {' Z# M* l. g8 Z2 u& H
           preSum[i] = preSum[i - 1] + nums[i];
0 S! q, F* \; P& \      }6 Z" q0 k& H3 R! Y7 E
       int[] res = new int[nums.length];% x  t$ @' y& C# S% Y: j
       Arrays.fill(res, -1);
; [! l. y6 \  a& w- |3 R       for (int i = k; i + k < nums.length; i++) {# H2 @0 u& |. f8 ?" p+ U& U+ M
           long sum = 0;0 g% E* P. h/ F3 _  Y
           if (i - k == 0) {- L9 d/ N( N: q
               sum = preSum[i + k];
- E( u* u$ ^6 w5 Z$ M          } else {) G( F2 M! j. u& b/ }
               sum = preSum[i + k] - preSum[i - k - 1];# e' G3 A4 z8 \9 P9 U% D" U1 L6 ]
          }, {/ y- l9 _: N. d
           res[i] = (int) (sum / (long) (k * 2 + 1));5 V, [* h) a- h5 P$ K8 E
      }
0 }: H6 l1 U& f. k6 I- e       return res;7 q. W* _# I- c% B" r( B
  }6 V4 @& R6 H9 r, O  u5 ]" F) R
}  y( y, B  Y! G3 T, A

! w9 g$ j" ^- O6 ?【 NO.3 从数组中移除最大值和最小值】* b7 v- q+ o& e' O# X: w7 j9 \- X$ ^$ g

, b3 f# U( r# `1 p解题思路
6 p9 G  ~3 ^. r# D+ P8 ?贪心,按照最小的花费移除即可。详见注释。3 |; g5 K) z7 i

1 M8 v: F/ f) b0 k9 n8 C: a代码展示
7 y1 \' |8 o1 C' G) o3 `: f2 \, G5 @9 z8 r
class Solution {
' i5 C9 m0 v! s2 X, D   public int minimumDeletions(int[] nums) {
7 W: r9 ]* c" _! f. Y7 ~. H       if (nums.length <= 2) {- I: t3 _9 a: E9 u
           return nums.length;
9 I& C! I. [! t  ]$ n, G; y      }9 N8 w1 ?* V% h! |' [1 y5 b
       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
4 T# |8 h4 a$ P       int min = 0, max = 0;+ h0 u, I0 p9 N
       for (int i = 1; i < nums.length; i++) {
$ r9 N& i8 f7 v7 r% z' ?           if (nums[i] < nums[min]) {
  S$ d$ E* a# r" o5 A               min = i;7 k( h7 M' P$ ^
          }& R: ^  E- E! i3 p% }: O2 Y
           if (nums[i] > nums[max]) {' ]2 {% ~& M( B5 V, k# E
               max = i;
, A3 Q4 s& R; B' F: A3 i2 `          }
' D# Q) d8 S4 A8 u. T$ Q! s9 W& T      }
8 M  |8 h0 F2 ]. P       // 要移除的元素下标为 max 和 min" e4 ?  Q& D7 @6 K' s
       // 此时我们只关心下标,谁是最大值谁是最小值不重要1 E2 o9 |* I& n# `9 M  p
       // 为了方便处理,令 min 为较小的下标
( y; t5 }0 P4 ~) u/ l- I       if (min > max) {
& s* Q: Y( j8 W( |9 Z2 {           int t = min;
2 }8 W. D" Q) U           min = max;
3 Z" M2 I: a, ]4 d* O) Z           max = t;0 q( x2 J) S8 w% k: K" V
      }
( [$ u7 R" ~6 |2 w2 v; W( x       int res = 0;- B6 z" t+ N9 ~- S: \/ ]
       int left = 0, right = nums.length - 1;
5 k" p. E! i% W0 E, k5 B$ P) }: ~2 |       if (min - left + 1 < right - max + 1) {
. E( G+ d. o6 X& O           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min9 Z1 v3 _* r. g: v' P' `
           left = min + 1;
8 p) o' ~% S& u( y6 q# ~  D, W           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
$ U; x( @5 Y9 k9 W( p      } else {
, R5 H" j" P) p           res += right - max + 1;
& E; i7 J: F/ [0 T           right = max - 1;
2 Y, c) A( O' F$ [+ |0 O. U: Z2 f1 ~           res += Math.min(min - left + 1, right - min + 1);
3 A9 ^. Z0 r/ i  X! ^0 p' j, K, e7 W/ L, O7 T" r
      }9 r& B8 x! j" `% E0 H) N
       return res;
' m8 t, R. @& z* n  }
9 R3 N* J- E9 n5 n9 z/ {% @9 B; \- }}
: Y9 X# B7 U' Y3 A7 L; D5 I: x
% V. G1 E. [/ W8 n7 u【 NO.4 找出知晓秘密的所有专家】
: @! X0 R; ]! _; ~2 g9 m" [7 X; D
解题思路
* u7 J" u$ x. P# s9 ]& y并查集,详见注释。
$ M( \9 L+ P4 d5 c4 a  h4 F  G; X  S' V0 E! S9 V8 G; D1 j
代码展示
6 T. l3 ^: |/ M' v% N2 \2 n  M$ w
# l8 K7 K4 J9 z! P  @7 ?' `8 x$ y: Bclass Solution {+ U% Y9 ~( ?$ r5 u
   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {9 M/ O+ H3 r* }
       // 按照时间点将会议分组! Z7 B9 P0 a' h3 W
       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();: b" O3 M4 J2 b4 H: c; C( P
       for (var m : meetings) {- R& Y# H- o' E. U. P
           if (!orderedMeetings.containsKey(m[2])) {
9 E1 Q+ C" J* V3 M+ n               orderedMeetings.put(m[2], new ArrayList<>());! F4 A# p; \) t& ]/ k: D
          }1 r) j/ D' q6 e/ m
           orderedMeetings.get(m[2]).add(m);) L1 a8 u6 Z# p1 [6 W( W
      }0 y% p8 f6 ~. H* F
       boolean[] known = new boolean[n];, Y7 ?9 D0 P* S
       known[0] = known[firstPerson] = true;
" r1 I, e8 t$ O, `4 h7 h3 |. K' I2 o       while (!orderedMeetings.isEmpty()) {) S. u9 F6 b! A: J
           // 按照时间顺序处理每一波会议
' ^! t- N( C! }9 S4 y# v           var entry = orderedMeetings.pollFirstEntry();
- l9 }4 Y! x. H3 P9 K           var curMeetings = entry.getValue();
5 V  @/ ]8 H6 R% w           // 使用并查集维护当前时间点发生的所有会议中,有关联的人+ e, x0 e6 X% P) Z% s. Q6 _* @
           UnionFind uf = new UnionFind(n);* K! J0 N% F7 y' ^& ^% h  Y! X
           for (var m : curMeetings) {) d8 g7 ~. u$ J! }6 m/ s! G' A
               uf.merge(m[0], m[1]);% k1 I! \+ P$ T9 ^% A5 z
          }+ z4 {+ I4 I# ^: [4 [4 G
           // 枚举所有会议
  m2 @8 @5 T  Z& V% r- O           // 若会议参加人 m[0] 或 m[1] 知晓秘密% T5 L, {1 P. V0 E) m3 e
           // 则把他们所在的根节点也标记为知晓秘密
5 {4 [8 i4 F6 G9 J4 G1 z7 k4 E           for (var m : curMeetings) {
4 f% L( [/ ?0 I9 H& H, i               if (known[m[0]] || known[m[1]]) {
2 R- }( t+ I4 O                   known[uf.find(m[0])] = true;
; x4 i+ m' V/ t) V8 n                   known[uf.find(m[1])] = true;+ K! z! c' j& c8 d* j7 m. s
              }
$ m& G0 T) _9 q# K9 C( P: d          }/ Y4 K1 G8 p: @
           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密
/ o0 n7 U- A$ O2 H" h           for (var m : curMeetings) {0 M8 K- |. _! K
               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {1 L/ _- B3 P1 d: K4 [2 G4 E
                   known[m[0]] = true;
6 g8 m1 M1 u( e: X                   known[m[1]] = true;
  K; k2 N/ r* F7 o( h4 X) n              }) l: e, m* o1 u
          }
7 W3 W1 ^+ G! p9 ?: Z* b      }
# g6 Z) f9 s& ?; R( o- ~0 N       List<Integer> res = new ArrayList<>();, M; M& P9 k$ L* J
       for (int i = 0; i < n; i++) {6 Z1 k: k! R, s/ _
           if (known[i]) {
+ i( ^% U% S$ l7 @6 Q5 u               res.add(i);
( E. V: J# n/ q' w. W( P          }, O, \2 u3 _4 F6 ]$ W: R* P
      }4 X& p! B! B& G! T/ Q! P: t
       return res;
9 K/ T1 L, ?4 H' M2 O  }1 R7 j, v  [0 V2 A6 a+ z+ i
}
5 ^( l, f# u( F4 s4 ^9 B; F  w) |2 k( k
class UnionFind {
8 i- q- m6 l" Z( o0 j( v   public UnionFind(int size) {. V' E- T! P% l; Y/ s* Z, V- w0 ^
       f = new int[size];
' c; d7 m* I" y% `       Arrays.fill(f, -1);
& T  n! N1 g" P, i' V; ]" ^* \  }
  p! w  x9 D0 t& Y2 S! P  D) ^2 B" l5 W, B1 J
   public int find(int x) {% ^+ S. s/ P% o! ?$ B# e
       if (f[x] < 0)
2 p4 a& a# l/ o  O           return x;
, U- ?: s$ ]2 P       return f[x] = find(f[x]);
: m  V+ L. G, Y6 \5 {7 y! S  }
- Y* m/ E. ]& M6 L! S+ R1 ~7 p8 v1 I$ T- K
   public boolean merge(int a, int b) {" {0 v/ E3 h) q/ M1 Y! h  b; P
       int fa = find(a);
: b: }; h+ M1 x1 g: P! u1 S       int fb = find(b);
7 f6 H: N( v1 j5 }  I5 d       if (fa == fb)
/ N5 ^) L! Y' |2 e$ P           return false;$ Q) @: i1 w3 q) t
       f[fa] = fb;& q( Y$ l0 E  A* K$ _/ v$ P% |% E
       return true;
" N# y' T, a: m7 U* J& d  E, `" |  }# f) r6 n% l$ S

  ]; k$ o; R0 @! D7 k% h) W0 F   public Map<Integer, List<Integer>> sets() {8 _8 ^$ k3 D3 G( {9 S4 o0 B
       Map<Integer, List<Integer>> res = new HashMap<>();! i' X/ V. t$ P2 y4 u
       for (int i = 0; i < f.length; i++) {
; Y; m6 e5 X# c1 h9 E           int fi = find(i);4 U; p; `  I: ?* i, |+ ]- L. e% x
           if (!res.containsKey(fi)) {5 I8 k5 E& d2 c! l# }2 T
               res.put(fi, new ArrayList<>());
7 G# g7 [& j# u# w; |6 B          }
) }, J- v; Y) G# e8 f           res.get(fi).add(i);
, m9 N3 @+ J: z& F8 F" u  x      }8 c* ?, `5 Y, q, Y; P
       return res;% I# R, \. u9 T- n  \' Q
  }9 }' V6 E9 B0 S' O- J+ N

" U# |+ i( b  K8 c! Q' a) F   private int[] f;
' z) f8 F$ w3 l}4 k: d; I; z  h; |  p, G
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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