找回密码
 注册账号
img_loading
智能检测中
置顶:如何加入2024届新生微信群

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出数组排序后的目标下标】
0 X6 O  R/ w, c. K2 R' o9 {2 h解题思路
- y8 b# O8 W! B- i签到题,循环判断即可。
; H, e# J1 c) D# D
  d( K* @1 \5 y* J代码展示+ z4 i* @7 q5 O1 m0 d7 q* l, y9 v/ k

) B- }6 |6 F: N7 oclass Solution {
$ q1 C8 N3 O6 h# x9 @   public List<Integer> targetIndices(int[] nums, int target) {
0 C! a' S4 n# v/ x5 w2 \       Arrays.sort(nums);
, c0 n4 Z" V$ O' b       List<Integer> res = new ArrayList<>();) j, {) E, I( p) l$ y
       for (int i = 0; i < nums.length; i++) {
; e/ w; A' r9 N5 b3 o0 @* X  i% X" F           if (nums[i] == target) {
% m  s" I' _# `: O4 Y6 Z               res.add(i);4 o' K' r/ P  {+ T+ u% a8 C
          }6 b+ l; [6 \2 d( H3 x$ U
      }
9 G* \4 V1 y$ k3 c* B9 Q4 q4 Z       return res;: S' K) o, L0 w
  }% D2 X: a$ g! W0 c2 R: ~
}, G- Q0 C( T5 }2 C+ F; {: V8 x
5 u: \9 t0 k( X+ Y  g. W" ^6 A/ Z0 M
【 NO.2 半径为 k 的子数组平均值】
+ e; w" X0 j+ Y) _$ G解题思路
& B5 M) p5 I! l/ R% g) B3 v使用前缀和计算区间和。注意使用 long 类型以避免溢出。$ q7 T4 G4 z# ^& _5 W, P
# V' J3 D/ c" p3 U% d
代码展示
. ~) c$ J) b, y* ?9 L, S  d* e
, f2 o9 U: z5 @$ }  p8 cclass Solution {( C3 ]9 t  O* N
   public int[] getAverages(int[] nums, int k) {* x0 D! H. V7 D% p# D6 y
       if (k == 0) {
% v- z+ u1 Q+ T& ?+ M9 K           return nums;
8 v3 u: ?' u, U      }0 J: j8 Z  ?. }7 Q; R* o( G- E9 H0 A
       long[] preSum = new long[nums.length];
" ~7 a$ T& U% ?) M       preSum[0] = nums[0];* R! V  [2 Y  \* L3 I1 h
       for (int i = 1; i < nums.length; i++) {9 l9 u7 i% p! I4 p1 W
           preSum[i] = preSum[i - 1] + nums[i];
7 X3 t8 R% F. P      }
% X( V: b! X8 H$ g6 G. K       int[] res = new int[nums.length];
6 v$ H7 o2 M. S+ u4 ~, Q       Arrays.fill(res, -1);( v! d, \- b) |1 _8 ]; i; [3 }" q* l
       for (int i = k; i + k < nums.length; i++) {
) H7 x! W$ @3 L6 E& Z% p           long sum = 0;
; n0 d( {0 V0 W" J2 B/ G           if (i - k == 0) {
6 B4 [0 i1 j& x* b0 A6 A               sum = preSum[i + k];
7 S2 j' Q/ |- V3 C8 l! m          } else {
- ^% I- R$ w: \( p: n' |7 \               sum = preSum[i + k] - preSum[i - k - 1];% c  _; S2 p8 h
          }
5 m! y4 O. z' f% G3 C2 A0 Z           res[i] = (int) (sum / (long) (k * 2 + 1));' |( q! E8 c3 S
      }2 n0 L" z: N6 ^/ d
       return res;) E2 U) @  ^) b; j  M5 S4 o
  }
/ l1 i2 d- s1 O$ h, u}
; e6 k% D0 [" i1 A! y* O9 q1 V) e9 A4 q% Q6 n, C/ o7 d
【 NO.3 从数组中移除最大值和最小值】
8 [0 O1 i" j$ _1 m$ b& J# A' }6 D/ \* G. d- }
解题思路3 h# @" e5 v0 \$ ~+ M& Z$ h. O5 o
贪心,按照最小的花费移除即可。详见注释。
/ r" b1 J2 W  ^$ H1 h( P
# G: e* P# u5 e( D. E5 D' k; Q: T代码展示
5 g* V4 f0 F$ @% S4 Y, f5 G
2 @; z7 g3 E& I2 xclass Solution {
; n6 q# p. W5 k; q! G9 I! g   public int minimumDeletions(int[] nums) {  M) s, V0 C# Y, a( N6 n5 H
       if (nums.length <= 2) {) F* |! m# Q0 n0 f, z
           return nums.length;7 W# z: F7 |  J& W$ Y$ K0 ^
      }
, H$ k( @5 [5 o9 a$ y# t       // 找出最大值和最小值的下标,由于 len > 2 且元素互不相同,所以最终 max 一定不等于 min; t+ z( A" H4 G5 V
       int min = 0, max = 0;
: |" [7 Z. t, r( t! t& f0 b* V( C0 ]       for (int i = 1; i < nums.length; i++) {+ _5 [; g* D/ Q$ y' @8 t
           if (nums[i] < nums[min]) {
7 l7 \+ V9 B3 f               min = i;. H9 z( c8 b& ?
          }
8 r9 Z. r& m- Z1 Y# @# i           if (nums[i] > nums[max]) {
8 n; P7 \" z+ i7 K8 Y" S, Z               max = i;3 w5 _6 p% a# ?+ U( z$ }# y, c  @( |
          }
+ J3 c( }' x3 x9 u      }
  Z2 B$ j! S* t" Q: y       // 要移除的元素下标为 max 和 min
# l- j  h3 |1 T, v" Q       // 此时我们只关心下标,谁是最大值谁是最小值不重要" c! ]0 u  ?% r( `, K: C
       // 为了方便处理,令 min 为较小的下标+ w0 Z6 o3 f% o8 `. d
       if (min > max) {) ?  h7 ]( ~+ E
           int t = min;
! j6 R" q5 w. K           min = max;
- k$ m+ |$ T( I% z. {           max = t;$ P+ H8 j  T" x) x
      }0 ]* c  P6 s% ?
       int res = 0;7 ?$ ]( e. U: u& n2 B
       int left = 0, right = nums.length - 1;
5 k7 L1 \: D9 ]/ E4 a7 M% ^       if (min - left + 1 < right - max + 1) {5 P; z& n) Q1 c+ T3 F6 U$ Y
           res += min - left + 1; // 贪心,移除 min 需要更少的操作,先移除 min. L) z( s4 P+ y" Z; e9 H& u9 }
           left = min + 1;
/ v) m1 Y; N5 _* T' [  Z           res += Math.min(max - left + 1, right - max + 1); // 然后再移除 max
2 O3 y2 Y+ Q$ l      } else {
+ q7 F6 V) l( ~/ n           res += right - max + 1;) l' X. O3 s, O3 v7 ?6 ?. E
           right = max - 1;
" n  ~4 R( \# {           res += Math.min(min - left + 1, right - min + 1);
# w0 X( f: r: p, k- p% v# N& C7 R  u  w- K6 z
      }. p. h! d, m6 i/ N: v) m
       return res;/ l6 Y) F7 I6 D* W
  }% m$ f# x. p' X& ~" T
}6 `0 _8 R- H$ Y7 |0 _' W" Q

: D; h" V) ~# F) l9 Z$ W7 t  v【 NO.4 找出知晓秘密的所有专家】6 n/ K9 a  J$ D3 S

: \4 J( I/ `7 Z! p" Z) F, V. ~; B解题思路
* b$ d  `5 `& Y* U3 i并查集,详见注释。
; p* q0 ^3 q" B2 U2 S! L
5 h  {" b$ O: H9 B7 B7 H代码展示$ l( Q: j- L1 E" L1 O0 u

8 q# n; X. d7 w  \) b$ `4 _( }class Solution {
$ Q3 J, Q" k8 z+ X7 }- k# V   public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
( G0 Z: U3 B; R6 _       // 按照时间点将会议分组: o7 p# B" l  t7 B% S. d6 r
       TreeMap<Integer, List<int[]>> orderedMeetings = new TreeMap<>();4 V1 B. h8 y- ~2 f
       for (var m : meetings) {+ X9 ]/ T' W" M) a% l5 p! D
           if (!orderedMeetings.containsKey(m[2])) {* R% l) q8 C& e, n/ N
               orderedMeetings.put(m[2], new ArrayList<>());  I- D4 ^' g* h$ ~$ v2 y8 c6 s
          }7 u& ^% `& f, ]* @
           orderedMeetings.get(m[2]).add(m);3 [% @7 v" ~- s" c3 z
      }
7 Z6 c- a. F. i, n5 V$ Q       boolean[] known = new boolean[n];
% }. f8 W8 q3 R3 L       known[0] = known[firstPerson] = true;
+ B# N6 F% i; d       while (!orderedMeetings.isEmpty()) {
4 i' A* G+ ?# N           // 按照时间顺序处理每一波会议
0 U, S: n7 {9 [$ e) O$ `           var entry = orderedMeetings.pollFirstEntry();
( j* i; t$ T- {# b2 s0 i           var curMeetings = entry.getValue();
3 g4 I1 `1 p* m$ }- A           // 使用并查集维护当前时间点发生的所有会议中,有关联的人
: A. t7 e8 A) b  B           UnionFind uf = new UnionFind(n);
& f; P6 j" t  M" i% a3 s; J           for (var m : curMeetings) {+ |9 v( d8 v5 N8 Z3 R9 y
               uf.merge(m[0], m[1]);4 _' l7 X* W  G( p
          }) F2 |- l' }6 h+ h( |' e& m  L# X
           // 枚举所有会议$ ^. x7 d6 Q. s! R; R$ E
           // 若会议参加人 m[0] 或 m[1] 知晓秘密
9 P  r3 _. D" u, a( B% o, o           // 则把他们所在的根节点也标记为知晓秘密- \- }$ l8 Q. c" K- v
           for (var m : curMeetings) {
: \& z4 b" ^% G- E4 q/ G               if (known[m[0]] || known[m[1]]) {" M* W6 h6 ^  c) @2 [' q  U& c3 z
                   known[uf.find(m[0])] = true;5 S% v: a6 I# Q$ N' C' C( X8 u$ B
                   known[uf.find(m[1])] = true;
* \! P# h! g6 Y  N7 h. V, a              }4 D1 g2 m. @  |1 Z# ^
          }
1 X7 X6 Y  g' h" ]7 ^+ }           // 枚举所有的参会人,若他们所在的根节点知晓秘密,则把他们也标记为知晓秘密: {* h. t7 ^# |, g7 ?- l  b
           for (var m : curMeetings) {  H! E4 x4 C/ \! U1 g) ]
               if (known[uf.find(m[0])] || known[uf.find(m[1])]) {
! l0 H  _& H& `6 p) L( y2 ~3 J                   known[m[0]] = true;
/ G* e+ a$ s+ Y4 u9 N                   known[m[1]] = true;
) E2 Y+ H5 V$ e2 E9 ]2 ~0 P              }; D: p. Z% C+ U9 c# W
          }
8 D3 p& D4 `. I/ W* j      }3 k( O6 t7 }& D5 I1 L$ Y6 E
       List<Integer> res = new ArrayList<>();
7 K+ [$ [' F  J       for (int i = 0; i < n; i++) {
- x6 N* i5 `8 o- B' P           if (known[i]) {  t% W9 v6 O" o. U2 U( v
               res.add(i);
8 D) ~6 e4 |7 g  w1 Y5 p$ B          }/ l* v, Q6 z3 v4 z! O( B
      }
1 i& s' x* p2 Q       return res;
* a$ }0 a; r  Z" C) S" c* G  }1 u& n7 q3 k7 v$ M  T  K
}. r- O* w( V7 [5 X6 Q" _# o
4 U3 k6 ~! N8 n# s/ p
class UnionFind {# v. a, u3 j3 @8 \" |' `1 @, J
   public UnionFind(int size) {/ P( z7 N4 C4 Q& K+ _/ e
       f = new int[size];$ g+ V  O& C; y  T; R
       Arrays.fill(f, -1);
( Y6 ~' H+ O' w  }
8 z& W" j$ w% s- n. G
0 k2 f' J8 Z6 u8 ?  X   public int find(int x) {# P) t5 I" d5 q# ~4 B0 J& N. t0 O+ H
       if (f[x] < 0)+ V5 X, [; q* a8 b) Z- a/ `
           return x;
4 G% N0 Z" K. k       return f[x] = find(f[x]);# V& F" E1 [/ J2 S
  }
& C, b) {2 H& L8 Y
. l( G$ n1 E3 L8 S3 W   public boolean merge(int a, int b) {: F4 f* J8 c$ q# l
       int fa = find(a);
& d) {9 ^; d5 n) ?5 j) ]3 a- k( h       int fb = find(b);
3 R/ s% Z/ H# ~  @& M0 E       if (fa == fb)) |5 O; Y& }. ^+ U- A$ |. B
           return false;
6 f8 A  p/ y- L. a9 g# Q$ A: I: l6 E       f[fa] = fb;
$ R$ B+ ]' Z4 f! E8 J/ u% B       return true;
' w+ J  V# i, Q0 T4 b) i  }
4 {+ C% A  Z. \5 p! A% F5 ?2 J; f. F# a4 Q& m# Z9 r
   public Map<Integer, List<Integer>> sets() {
) p8 v, k9 M. T( l. w: B# b       Map<Integer, List<Integer>> res = new HashMap<>();, S$ K3 D3 L* {0 A' F
       for (int i = 0; i < f.length; i++) {
7 }; J0 g1 }: P- q: P           int fi = find(i);4 ?3 {  y+ V8 e
           if (!res.containsKey(fi)) {. ^; o/ ^( @8 ^( x% T0 V7 V
               res.put(fi, new ArrayList<>());0 K  F) a+ L1 [% g0 I$ V* O, ?  M
          }
/ A1 X6 L3 u* C) o0 |0 g( Q7 m           res.get(fi).add(i);
5 q- Q+ y, _6 @3 v0 }: E      }* t. K/ ^9 R2 v* V
       return res;0 f- ]9 V7 e& K' x2 t9 t% v% V. w
  }5 g% j$ l' V! X; {

1 h, L5 Y4 d4 ^; n% y5 u- h9 e   private int[] f;
# J+ D$ [+ @' F}# U* g4 p, d# d* T4 g& q  i# ^
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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