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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】9 @3 X0 [$ L4 @% ?
解题思路
" q' b4 q: P* c) M/ r& g& o, u* p签到题,循环判断即可。# _2 n3 s- \$ |+ e/ K
) {8 {3 A: n5 p+ w: b8 L: a8 k
代码展示
/ [; ]& F1 B3 W" ~9 [! a) c+ R8 t8 F: J4 F' ~& C
class Solution {( @* w2 {+ M4 i
   public List<Integer> targetIndices(int[] nums, int target) {& M- Z6 L# t2 f* r' \8 d. Q" @
       Arrays.sort(nums);
+ {: o. F% c# D; U* {+ G! s0 L       List<Integer> res = new ArrayList<>();
* v1 `: T, o9 X4 _       for (int i = 0; i < nums.length; i++) {
' I0 T/ w4 Z0 G( i5 a: @           if (nums[i] == target) {
" T  U* E" h! h6 j               res.add(i);
  p' r( ]3 u$ X1 |, _$ _; @          }: I/ I8 v: g, S
      }
% @/ N! U4 r- [$ o# S5 }       return res;
. W! d- X7 S1 @0 m& M+ O0 L! m3 H  }
+ m& r" O; [9 W}
6 U; L& L8 U$ |8 R0 S( q
5 \6 x$ A9 n. ]4 [  ^【 NO.2 半径为 k 的子数组平均值】
8 u' E6 |7 y) r& _- {5 Y解题思路
' l$ N0 ~, i7 X4 V) i9 r使用前缀和计算区间和。注意使用 long 类型以避免溢出。/ _. p3 t, v) V
" \9 P" N6 T8 O: B
代码展示
6 c7 a4 m" C5 b5 \0 f/ m9 L5 h* ]  y) T( B: S- n1 |. t
class Solution {
* A  a6 g3 ?6 j! [  i0 m3 K   public int[] getAverages(int[] nums, int k) {
# L, w/ v; o+ w# `" s       if (k == 0) {
% D3 T+ J5 \9 p% \- t0 t' M           return nums;
$ q3 V5 b6 [& r6 y      }
1 G% F/ |# R5 K  a       long[] preSum = new long[nums.length];- G; C% D  w! ?
       preSum[0] = nums[0];
3 h' H2 ~' B$ y) |3 ^1 ^6 K$ M/ g       for (int i = 1; i < nums.length; i++) {
; o% L8 x1 s! [0 d- Y0 x6 w+ K5 I6 Y           preSum[i] = preSum[i - 1] + nums[i];- X( [: @9 `1 E* L# p- F1 O4 W) i8 S0 O
      }3 p9 j' u* T: Z% A% D
       int[] res = new int[nums.length];
( J' @( K- c2 y) Z! e" S* Q" v       Arrays.fill(res, -1);
8 W0 H( m: W$ D* x% d2 e       for (int i = k; i + k < nums.length; i++) {
7 @. c9 ^* M2 c1 b+ N# U. Q: `           long sum = 0;+ n. m  Q) {  ^2 _4 z
           if (i - k == 0) {$ Z, B( z& y" Y
               sum = preSum[i + k];; t5 ]7 C* W. w
          } else {
3 i0 g2 i% Z& q/ j. ?' d               sum = preSum[i + k] - preSum[i - k - 1];9 M: s' w8 M+ |) t- {, ]
          }
6 g( j4 x% i* @# T           res[i] = (int) (sum / (long) (k * 2 + 1));
+ |( @' F8 I* e+ J3 l      }4 q( h2 U! H) N  y- G
       return res;
7 K& Y/ ~& ^. x  }$ v9 f+ [; V1 a1 E1 q0 b  p" D
}" [. r0 K9 Z/ @5 b+ }/ N8 e

5 ?8 b" B8 F' c【 NO.3 从数组中移除最大值和最小值】8 }. K) n+ K* D' y5 q
6 i: J& e/ a) |5 ]0 R$ d3 s
解题思路( y# l" G" w- i: J/ J  c
贪心,按照最小的花费移除即可。详见注释。
% J- j: r! ^+ g& }0 a% Q. a3 L
7 n7 V2 X% t" y0 g: \代码展示+ A  w' O5 s- }) s: a
( c1 h; H3 P/ f  j$ c: G
class Solution {1 {# h/ ~9 r( g* x, ^1 H0 s
   public int minimumDeletions(int[] nums) {
$ Y2 B6 U( n3 R1 ]! N% [8 P4 r       if (nums.length <= 2) {7 E; j8 Y% `7 d1 i
           return nums.length;' k6 b( ~% ?# M* ~% ^; U6 U
      }
7 ~6 ^. F  M7 Y+ |9 u  s       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min
' q* M. |$ B: [  o7 A       int min = 0, max = 0;) M8 Z0 ]# r# A4 y" d
       for (int i = 1; i < nums.length; i++) {
7 v" ]5 K; s1 j8 P           if (nums[i] < nums[min]) {
$ P" Z$ j$ h7 ?0 i  R8 |               min = i;
( J, |4 K9 U* v" d7 g+ i0 W          }
% S* S8 N$ s7 r$ F" s# b- }           if (nums[i] > nums[max]) {
* e2 \4 N8 y9 F; D               max = i;2 R! m& S; W( t. X
          }- U4 q4 W( X8 p& Z: b* T
      }
& L8 L' E1 V# Z: a2 s: O- t* D       // 要移除的元素下标为 max 和 min; }! X8 _1 g, d& z2 f
       // 此时我们只关心下标,谁是最大值谁是最小值不重要
3 z! d' v- ?' \/ i1 C- r       // 为了方便处理,令 min 为较小的下标3 m5 w9 T* C+ M0 r, X8 C7 n5 U& `1 w
       if (min > max) {
1 j8 ~' C- W% `! [# t, x/ G0 c           int t = min;  r" s' i; I+ C9 Y
           min = max;$ A8 ?9 q/ T! a6 ^5 v) k
           max = t;7 x4 s! ?( J5 _! i1 a6 T# p# g
      }
& `' ?+ ^3 _( h& V# N: H       int res = 0;6 g* C1 z& s6 `3 a( r5 m& z
       int left = 0, right = nums.length - 1;3 i2 C) B7 Y3 u' v# i) E
       if (min - left + 1 < right - max + 1) {8 J5 ^# i) K6 i- T, F9 Z/ A! ]
           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min) }& F4 }/ Q& R+ n. c
           left = min + 1;) _+ T1 l  K" Y9 `2 v$ h) m" `0 c  G
           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max/ |0 e9 }8 _8 ^9 w: |
      } else {
6 s! a! u0 l5 |, t, ~6 B           res += right - max + 1;% T% _, f2 |0 p
           right = max - 1;4 H- i1 j  ^& x; z4 q
           res += Math.min(min - left + 1, right - min + 1);
% J6 t; Z4 F/ X' i9 s
1 D* Z* y' @6 S3 h. _& C) v, {      }/ q5 j% b& U6 @, U3 C- W$ J1 g6 U
       return res;
" u+ G! `2 m4 ?; b+ j$ K  }* K4 W+ s: F  C: a9 R" p
}
! J% J: a! E/ y9 ~) G
% P* M2 O! d+ n4 s$ `4 A& [) u. Q5 D【 NO.4 找出知晓秘密的所有专家】
+ I8 K+ R. d* b' u
. k! q4 X% I# t$ t解题思路
" ?9 {3 P% t6 J7 |' D7 ^并查集,详见注释。
' y  `; k4 W6 v( v$ N: C' @, d
- G, e/ W$ w' _8 v" t$ t5 y& `代码展示9 ]) X. e1 D% E. h+ ]

- o$ ]( q* v  e* lclass Solution {0 F  N* |- Y) ]4 f1 Z
   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {- i  i) X* |" U; O( d5 X
       // 按照时间点将会议分组2 ~6 A! t; r# F1 Z
       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();
5 i; Z9 l: g0 _- r. }5 d/ l. F* H       for (var m : meetings) {
' i7 N* Z# @  }8 ]           if (!orderedMeetings.containsKey(m[2])) {5 b/ c! s  K6 X* l5 Q
               orderedMeetings.put(m[2], new ArrayList<>());
* E5 {. J/ x/ ?+ m- s7 w          }
) b1 l( Z4 z$ u- z  s2 f  C           orderedMeetings.get(m[2]).add(m);, c- {6 e* b3 _3 z' n- Z# F
      }
, x$ p& J+ P- U+ M4 {0 b       boolean[] known = new boolean[n];
# j, G. E# v# `1 C. `       known[0] = known[firstPerson] = true;
' A% ^2 r6 `+ k+ r  ?! \& [       while (!orderedMeetings.isEmpty()) {9 S+ d0 m4 E7 g( z- P: p9 s3 k
           // 按照时间顺序处理每一波会议, z% P( G+ I/ C* Z% R! ^
           var entry = orderedMeetings.pollFirstEntry();5 a. x0 f" V0 e* r  [/ a
           var curMeetings = entry.getValue();% N/ p7 A* i2 S% j# L) U* A0 p6 O
           // 使用并查集维护当前时间点发生的所有会议中,有关联的人: Z! h3 ]& h- c0 ~9 W7 o! _
           UnionFind uf = new UnionFind(n);# D* H. G% N4 P- i
           for (var m : curMeetings) {. b2 d- n3 N* n5 N5 X! D9 M
               uf.merge(m[0], m[1]);
- M3 d+ ^5 V3 q8 x5 j9 V8 o+ N$ F          }
3 e4 C; x5 w- v6 E5 B6 C           // 枚举所有会议; W/ v; |, M9 B+ F
           // 若会议参加人 m[0] 或 m[1] 知晓秘密
4 j, T. x( s' c+ X, H           // 则把他们所在的根节点也标记为知晓秘密
+ F# o/ \' Y: i  `, s( V           for (var m : curMeetings) {
1 c* f7 ^8 N  J' @               if (known[m[0]] || known[m[1]]) {
; x" ?( m5 t+ A; Y                   known[uf.find(m[0])] = true;
# y( D- ~! d* K                   known[uf.find(m[1])] = true;' K) H5 c4 N4 v$ i
              }
% g4 r+ K  F$ G( H4 k( u% }          }2 n: ^3 ^: _, H) j5 P- s7 Z8 F
           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密7 {, v# s" v! L  @8 N- A
           for (var m : curMeetings) {
. o: G; j2 ?1 d+ a7 W2 n& f1 y) o               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
9 C5 }: i/ j5 D* z                   known[m[0]] = true;
8 s: b9 s- N# E. J4 [- F                   known[m[1]] = true;
0 c5 N6 f/ o, L$ J8 C8 u, |2 y              }
' t! j; v  s& _- @9 [6 ]$ ~% W          }3 N, {. L& Z3 g! q
      }3 ]7 ]" ?' o  }& l/ F' v
       List<Integer> res = new ArrayList<>();
. ~# z# j5 E1 [0 M/ ~9 t; j       for (int i = 0; i < n; i++) {
- Z2 t' U# Q" I8 D1 z           if (known[i]) {
$ o/ E6 W) g( \. K: o4 b               res.add(i);6 w) U" y6 C/ X, _$ `
          }
/ l, |# T6 D$ ^% v' \9 G      }
3 O. s  k% d) d% r       return res;
8 F( |" Q' }% G9 \& Y# G  }5 P. r* ~/ S& x" A
}  V/ U: g5 l* P2 M: ^
% ~5 V) u* n; n7 O+ I
class UnionFind {
, d' p- F- n2 |& P) F   public UnionFind(int size) {- `9 h; H+ \: q: O! Z. E
       f = new int[size];
2 G  ~6 Y( w) e( s       Arrays.fill(f, -1);
  F2 b/ x' V- I! |. p# L; S3 C  }
( O9 Z4 k" I% J6 z
" O% i- h$ W4 ~' o5 p) P   public int find(int x) {
6 `% g* U" c  t2 B       if (f[x] < 0)( R; `1 a8 k3 ^, Y' ]  \+ b- }7 F
           return x;
9 R# D- @7 K8 E( ^       return f[x] = find(f[x]);) C* I. C6 C. a. ~0 e
  }
6 V7 d$ ]: @$ |" A8 Y8 E- [3 t3 j+ J4 ~5 {; {1 |# J& m8 M4 ~
   public boolean merge(int a, int b) {5 y, o. x) q8 Q  Y' r! [/ n
       int fa = find(a);
0 E3 O: ?/ [. K# k5 \       int fb = find(b);
& o, ?3 h/ ]" j; R       if (fa == fb)
" K3 F6 n0 `: I/ h8 t" ^1 G           return false;# A7 _; c: I6 l9 S
       f[fa] = fb;
1 d1 ^7 K# \7 S% }       return true;* }1 w: l6 t: q& h
  }
7 v; a. M" ?5 w* Z% I+ F% u) s7 E6 t9 J7 t
   public Map<Integer, List<Integer>> sets() {/ E) A0 `" W) e( \) P/ W3 t
       Map<Integer, List<Integer>> res = new HashMap<>();
$ S- W) i; ]. d       for (int i = 0; i < f.length; i++) {9 Z: d- j" _$ G% x9 ?
           int fi = find(i);5 Q. o& ^9 r0 z. n* L0 R2 V+ k$ P
           if (!res.containsKey(fi)) {
) f( {5 F5 G$ z( P6 r4 ?               res.put(fi, new ArrayList<>());  |+ E8 `* w) w6 K' j! ]
          }
% {" u& ~  Y% l! {1 u" a1 N           res.get(fi).add(i);
. \; {6 o6 B) V: g6 Z4 E" P      }
2 ^' c7 h* p0 q0 ?; [  N       return res;" ~; B# s. t4 U
  }
0 T$ e, X4 [2 Q6 P- P
- }# q* \% T0 q   private int[] f;
3 b$ i2 Q  J6 H8 P. d1 b( \; c}% r/ {6 \4 g) j; d
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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