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

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

上岸算法 回复:0 | 查看:2670 | 发表于 2022-3-24 05:53:38 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 统计数组中峰和谷的数量】  Y1 c+ g0 @' C7 c& X& G

' T3 K+ `7 [4 V* H- g解题思路1 o( M9 j6 N- I  I) y5 b1 l8 W
先去重,再统计。
- p" c# l. \5 F" I/ n
  k0 P+ h2 }% Q6 \$ v- }# d代码展示1 V9 a. q- B8 w6 C
* X5 c' h# c& _0 m7 `$ w6 T- |
class Solution {
! V1 M* p% \6 I( E) d+ M3 Z   public int countHillValley(int[] nums) {
2 q$ E6 B3 g5 F- d! ?       int len = 1;
2 e) Y% k3 p5 }       for (int i = 1; i < nums.length; i++) {6 r  U+ S4 _0 L& @& ?7 r& s* E
           if (nums[i] != nums[len - 1]) {6 i" {$ K0 ?: h* T5 ~# k( s
               nums[len] = nums[i];
- L! |  e8 O/ U6 B; y               len++;$ P9 A2 U) A* t' Z0 Z; w
          }
# Y9 O( O' Q" L      }
! d* k9 C; P# e1 V: V* o3 u       int res = 0;) c! A4 l5 x5 c, m
       for (int i = 1; i < len - 1; i++) {
3 n$ c3 a! B" r& F! ^- F, ]           if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {- j$ S5 i2 \; @9 w0 O6 Z
               res++;" A, B6 h; s8 @$ \  H3 }7 v
          }9 K2 g4 N6 W7 o! R4 a$ o
      }
2 B; v1 g: J+ U8 Y       return res;0 n5 c  ]1 X2 E4 ^! ?7 n
  }
# e+ X% l& Q' l/ }* A( P3 k* U}! n. {7 W3 w/ v
1 y9 d& s3 V* a

0 j; {4 R' w6 }( _" t【 NO.2 统计道路上的碰撞次数】
. L1 f" Q, h! i7 I3 d4 d
( c1 P4 F4 |2 o, m- q! ~+ T解题思路
1 A; k( @7 g$ l% ~& |. d% b6 s从左到右遍历,维护左侧的车的状态,有两种:
7 D  V! I) a$ X6 z# T, M- O
; k  p2 C4 J/ s若干个向右行驶的7 \1 ?, t, P; g4 v0 L

- O) N$ k& [& W停止9 D" I" ]2 O" V& u, Y5 @7 d7 Y
1 @5 T; C- k5 Z  j  _( M
代码展示
' e. j5 z5 n$ o6 z/ c/ j  T- T1 K: j; \) s  B- |
class Solution {
+ _, a6 H, \( y' X" ?   public int countCollisions(String directions) {
% I5 _/ I/ [3 c% p       int res = 0;
$ ^& @2 |/ V/ \6 D, y       int S = 0, R = 0;: ~5 a; R" L) p# p0 E5 i8 e' R
       for (char c : directions.toCharArray()) {5 |8 W' `/ b* q5 W% L) V6 N. ^3 Y
           if (c == 'L') {
4 Y2 @5 m: H! `6 |- B( K               if (S + R == 0) {9 w& M) B; m! ]* Y4 M
                   continue;
+ O$ W; m3 `8 I              }
  X& }1 v  C' S! C               if (R > 0) {0 J: X6 m7 O+ a! q5 l
                   res += R + 1;
" U: e8 Z' k, s  p( ~              } else {6 v, @: W3 {5 Q; W" H# [
                   res += S;
( m8 u$ }: x3 i              }
) B3 W2 Y8 g$ L/ g- |               S = 1;
, e9 c4 T5 f% u! [" |/ Z6 y; v               R = 0;
# ~* Z6 }9 z; m2 N; K: G) W          }
  K7 w* |; S% U0 N           if (c == 'R') {
* w, K6 ^; s* H6 C. V+ h6 P  x               S = 0;
( ]+ P. U" n1 B$ E2 j/ G' _+ B               R++;4 ~" L7 t+ L: v/ q. A
          }
; e  I! L7 I6 T/ ~- v$ Y           if (c == 'S') {3 Q9 S) ~  j+ k8 `' }
               res += R;' x8 [3 I3 |% |
               S = 1;1 a& Y0 v3 G3 b- Y" i* g
               R = 0;
: K$ T, X  x7 b4 `, R- s/ T; F          }& L6 a/ c5 X0 R
      }8 |, ]1 {# m# \1 d0 U
       return res;% I, \6 ?# B. f: Y( t
  }
9 f( a0 U& b) R# }* f3 c}  u- e5 R# n7 a, F$ m

9 M9 q/ v9 Z' j1 e+ z; w+ W
8 T2 I2 q! c" w* @2 R5 r5 }) q【 NO.3 射箭比赛中的最大得分】
( u9 @. ^0 P# J8 j7 l' ?2 \& a+ ]1 @$ d2 _; {
解题思路2 a- u/ l3 i) f" E, ^
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
/ t; ]) [# `4 S( }2 L- D; m
. o3 @1 y. t9 {贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
  v2 q8 Y+ N9 q9 Q2 e- Q3 ^* E' t4 ?" \/ H. b
最后多余的箭可以放到位置 0.; @# r3 z& V5 K, b1 d
! b/ r$ k2 I3 ?1 w* X0 y
代码展示
1 Z4 o; M' B. @4 w5 _; b/ B5 I: v' d& v7 q8 i
class Solution {
& i% {2 M0 ~5 R   public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {
3 D* D3 E' [8 B       int max = 0;
/ ]6 |7 W5 e) @. h1 v; o# {$ u       int[] res = new int[12];
7 s) F# Y9 ^+ ?5 q5 R  e       for (int i = 0; i < (1 << 11); i++) {
" A- O8 C0 N4 K1 y, p6 U           int num = 0;* n* ?) B& O2 G5 T1 T3 X
           int score = 0;
4 K$ v2 o- R) K8 S* R7 o           for (int j = 0; j < 11; j++) {
1 w' T9 `4 c0 U/ Y               if ((i & (1 << j)) > 0) {
# b- f% Y4 g7 @                   num += aliceArrows[j + 1] + 1;. N) S8 L5 |: c, x) i1 j0 ^( {) \
                   score += j + 1;' Y9 y. B4 [) N/ W- }5 N
              }
8 b4 Z5 v6 d. f) J          }
; E$ q+ q9 I* Q: U  u5 v8 r           if (num > numArrows) {
7 b+ d. i5 [8 E1 D- y               continue;
6 F  j  X* B  i          }
/ B, B7 K% Z" J" R; q           if (max < score) {
* b/ A; o. o9 z3 j. L% ?               max = score;
& Z7 A1 q. |& U# h               res[0] = numArrows - num; // 多余的箭8 N8 N" M8 N9 t! a9 {
               for (int j = 0; j < 11; j++) {
5 d0 v; r7 t) ~) }9 n0 f9 u1 b* M                   if ((i & (1 << j)) > 0) {: e% A( U$ Z% _; L  ~) ~
                       res[j + 1] = aliceArrows[j + 1] + 1;6 A6 D$ y. I( }' z' Z
                  } else {) `! p* B) l0 V3 w) i1 {; e
                       res[j + 1] = 0;
0 ?7 e5 R# B' @2 g. F- Y, u7 G, K                  }9 N$ p- `% j) j; K
              }. \% w% D+ W. I* v  C- x
          }
6 N7 i( S4 I8 V" N      }) f8 l3 w* N1 b/ {" P- U
       return res;
) c/ s+ C5 w5 y  }
. d3 r. ~. F! R9 I2 f& ~}
4 D3 A$ @/ N1 j2 g$ g0 A0 ?" X! E$ t- {' M

. Z5 l. T. s' I【 NO.4 由单个字符重复的最长子字符串】
+ R# [: o: w4 _# k
$ x! ]1 n, ~) m# K) A解题思路' Z. g# J% i. z- `* o5 Q" B
灵活运用 TreeSet 即可,详见注释。
$ p* c* \2 j( M8 v1 K: y/ m# n- ]+ t6 ~: s3 W" \( R
代码展示
& q0 W% o% z& }. S8 u1 r$ z  Y
( m5 G  G$ `5 Mclass Solution {, }; \5 j( ~  J2 M
+ n# X( Q! `2 _" n" I
   // 一个 Interval 表示一段连续的字符
. T% H0 n" X2 s# [1 f7 Q. s. g4 l   static class Interval implements Comparable<Interval> {
# x  J( t# y5 \9 ^0 _+ j* i       int start;
# V9 p7 G" _2 y6 F& M% B       int len;, [1 S4 a8 ^: i5 S) c( U
       char c;
  Q) u# a9 S: U, q; u' m* d; V% c; q! S; z/ |0 B2 s
       public Interval(int start, int len, char c) {
4 ^* y- U8 o: a- G           this.start = start;( W! {& y9 S' y1 W9 O4 c  q
           this.len = len;
0 }1 h6 i' F' c+ W& `3 Y           this.c = c;* \+ D; R4 v. i- b. I
      }2 [$ I5 _# H% g% [2 A  C

; |; q' `1 C& J! e  N; y5 \       @Override
$ h( V, v  q$ s/ k% H       public int compareTo(Interval o) {- ^( I' N4 p* G" y/ R1 T5 ^/ f
           if (len != o.len) {- u* w4 n! W& w' F% Z
               return len - o.len;1 V0 x0 C0 U: c' ^1 S8 l* u
          }' e9 o6 r. l9 M
           if (start != o.start) {5 \- U' ?! Z3 I- U1 J
               return start - o.start;9 m( w# I% h) N$ `3 g! r1 M, m
          }
, ?* V& R* \) b* s0 G           return c - o.c;5 r4 M; o6 n" b* A: Z" O+ N
      }2 {1 L! m9 q8 M8 _! A5 f, A
  }
5 N" b( M& Q7 K2 d" E! V& g- s7 G$ C9 R. v! K! i# ~1 r
   public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
  [0 E2 f8 K- b6 [       // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理: V8 c& L; |+ V( k, A" p& A
       s = "_" + s + "_";
- Q1 B8 \2 q9 M, q# _       // allIntervals 按照 len 排序全部的区间
" _8 q; u' l) _/ V5 u6 z; }       TreeSet<Interval> allIntervals = new TreeSet<>();
! E2 A3 ~3 P) `8 z( o6 J7 L       // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序
. \, M- T. y6 g3 ~! \6 V- g       Map<Character, TreeSet<Interval>> intervals = new HashMap<>();  x) [, G$ h, w) v. F3 }9 e
       for (char c = 'a'; c <= 'z'; c++) {
& d% q# i5 e& h* P5 N           intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));( Q/ I7 t6 G3 y( t% T
      }
$ z- q7 W( n) C6 q! y8 k       intervals.put('_', new TreeSet<>());; E2 `, j7 C' y2 W- b2 n

) L- R3 Q) p. Y) G2 x       // 遍历 s 维护 intervals 和 allIntervals
9 Z, }+ L! i! D  q- P1 H! }5 H       int last = 0;
0 M1 [  z: q  {- ?8 t) e       for (int i = 1; i < s.length(); i++) {
0 [: Y/ e% I  z1 w           if (s.charAt(i) == s.charAt(last)) {, F$ ]6 D8 E! y2 O6 Z+ a
               continue;( w+ _7 v, a8 E% Z2 |, J
          }& g4 @2 W  `9 p. K) |; r# u
           Interval interval = new Interval(last, i - last, s.charAt(last));* n% K. U& O" F. S/ ]2 [
           allIntervals.add(interval);
! a( Q& K1 r; p1 ^. s& U           intervals.get(s.charAt(last)).add(interval);4 l0 z( d. i3 i* D9 @
           last = i;
4 T) {7 {8 t& y- ^5 J      }5 f) i* |+ _4 h0 E3 ]
       Interval interval = new Interval(last, s.length() - last, s.charAt(last));
  r& S3 p7 s' K$ y$ t1 x       allIntervals.add(interval);5 }& A# P  l/ C2 A
       intervals.get(s.charAt(last)).add(interval);# _, |- K, o* M9 i
! N2 u( Y' [' t: I0 a
       // 每次 query 调用 maintain 维护 intervals 和 allIntervals
. }9 Z0 X4 F0 A$ }       int[] res = new int[queryIndices.length];  F# j) `. j9 ~" c
       char[] arr = s.toCharArray();0 ?" t: Q/ ?1 O& p
       for (int i = 0; i < queryIndices.length; i++) {
; K! N( E: m- q4 U+ T           res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));- Z* M2 ^) ^( i9 E3 X
      }
& @4 ~; G  K% y( [0 h5 C, n4 I       return res;4 _# w. e; a' @; F! d" v3 u
  }
5 x7 I& p# p+ I, Y% Q! z3 g
9 m, }+ {9 u& |   // 将 arr[idx] 替换为 c" T, Z! v' d$ ]# u
   // 维护 allIntervals 和 intervals
1 D2 z" I' j, E# u; p   // 返回单个字符的最长的子字符串长度
2 y+ c/ \& K- Z- v5 K   private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {; a* k( O& M) G0 L
       if (arr[idx] == c) {! T: X. L5 K* }2 W+ k9 ]3 f" q; u
           return allIntervals.last().len;8 `+ [& n& B6 D* p
      }
1 m* t3 S& x6 G+ u% @+ b
5 c! P0 e( L3 R; J( c) x. v9 K       // 维护原字符 arr[idx] 的 interval
3 j" Z  q/ q4 g4 i. d2 Q2 n       var treeSet = intervals.get(arr[idx]);8 Z6 H7 U  n4 q  e
       Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可9 b$ a* b0 t; ]' P) A) J. {
       treeSet.remove(origin);
# ~8 Q$ e; P1 U5 q% o, h9 ^       allIntervals.remove(origin);) j" q+ D$ [9 B: `3 Y4 H# S
       if (origin.start < idx) {
- C" }: i) G# G' g           Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
) ]1 t6 g$ N7 c1 S/ o# J( Q" t/ E           treeSet.add(interval);
$ P' n7 B: [8 O. \- e6 Z           allIntervals.add(interval);. R. F: }8 M1 e/ t
      }7 }3 n9 d* w# Q& `& Q# T8 q
       if (idx + 1 < origin.start + origin.len) {
) j( p: }# _/ ~- X5 e           Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);5 c- w0 M( g! W, G$ {( s- e
           treeSet.add(interval);
1 e8 ]& V% d# f6 }/ P' W. p           allIntervals.add(interval);
" G, p. z2 V1 c4 Z  E6 \      }" L" o, x' [  f, m# A  W! p" B) K
  U6 z# w" A1 x' q+ Z. c
       // 维护新字符 c 的 interval. ^- Y) c8 M. l# \
       treeSet = intervals.get(c);4 n1 J3 r8 ?' e
       if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接9 @5 e& j% i- }' b
           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));. s: O5 k  H' @
           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
4 E8 ]) G: z; a5 e. c           treeSet.remove(left);, \' A+ A- B5 a4 X% j$ R' j
           treeSet.remove(right);
1 D& _. U4 Z5 k6 S- v! j' O           allIntervals.remove(left);
* {' E: R& V! o0 L           allIntervals.remove(right);
( S! G) N1 {& ?  o& Z           Interval interval = new Interval(left.start, left.len + right.len + 1, c);4 R) l, T6 p1 w/ ~/ p* e/ ]: @
           treeSet.add(interval);
/ t( l. q% Y' k. q; @           allIntervals.add(interval);5 X% N2 f2 W" P* H8 q$ Q7 ]
      } else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接( b7 V7 s4 v/ }
           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));1 D) p" I3 \5 v) u& y- A
           treeSet.remove(left);7 S  y- z' y6 \1 M$ m$ C9 z) Z
           allIntervals.remove(left);/ N- }$ n" H; Q3 R6 ]3 |$ g
           Interval interval = new Interval(left.start, left.len + 1, c);+ h; x# }9 ]6 ?  k  M( `& E) n; B
           treeSet.add(interval);
" v2 W- m& E" R3 _3 U           allIntervals.add(interval);$ w$ C( `8 b! T; H
      } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接
% Y; h! R& g# z( t           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
6 S9 A2 u/ W. I4 z9 f           treeSet.remove(right);
( v& J: ~4 w; x$ O1 }( o           allIntervals.remove(right);6 {0 k2 p! G+ _
           Interval interval = new Interval(idx, right.len + 1, c);
, I0 |$ T+ Y9 O# y           treeSet.add(interval);  k- m% z. j6 j  L% a
           allIntervals.add(interval);
/ {( O9 u) I5 x6 I9 H" c  R      } else { // 单独一个
' ]: u6 S! Q. [1 J# }6 d" j; n9 W           Interval interval = new Interval(idx, 1, c);
( s! q+ ?% z; U6 A, }( v1 X9 D0 A. c           treeSet.add(interval);
; f: w: C) A, ?: C8 ?7 R           allIntervals.add(interval);
( F. Z9 v  f2 j7 }% t% Q* |      }
) U) ~# n  h4 m+ W, Y
% m* Q6 K: M1 ^! m9 I' ^       arr[idx] = c;/ i$ f4 z& R7 t  }
       return allIntervals.last().len;3 ~! K7 e' x* W5 @
  }: U2 K+ o  ?! F$ ?/ L) D/ Z5 P' h7 z
}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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