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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 统计数组中峰和谷的数量】' V/ L% T% D( N
- ~  A0 m1 U7 b; B+ h) d, B9 u
解题思路9 V1 J6 B9 q2 `% w; x" t' I0 S
先去重,再统计。7 C; e# q6 X: g$ J# T

, }9 A6 b( H. Y  ?8 `/ z代码展示/ _1 x  Y* S: T' M

. ^$ u9 f/ f6 L8 v0 e- o2 j! ^  G: \class Solution {
% n( S! d3 k$ Q2 i- I   public int countHillValley(int[] nums) {
1 o' u4 `* r! I5 i       int len = 1;
' p% l! ], F+ n       for (int i = 1; i < nums.length; i++) {# b6 X) H4 b+ `
           if (nums[i] != nums[len - 1]) {
" V/ _) j+ M2 m) \5 T7 [3 B, G0 Y% d9 E               nums[len] = nums[i];
' Y, i9 H3 g4 k& R4 B               len++;
1 Y) k) f+ t/ \9 }          }
/ g( l: o6 n3 _' X      }0 q+ F/ M3 J9 c. O( i; r5 c1 Y
       int res = 0;% |  X/ S5 p, |& F! k' H
       for (int i = 1; i < len - 1; i++) {2 _9 C. l& F4 L! |- A2 R
           if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {
& h4 h0 N; s* {2 S               res++;
  ^7 w8 `$ n  \3 t$ v, s          }
% ]4 |6 [0 Z- z9 O" ~4 B' y  r2 |      }: ?% M4 Z3 e0 y4 z7 U( V
       return res;* R  A" d0 H6 ?5 i4 w) i2 R) h# X
  }7 E7 }7 _) U) J* D  Y
}
; r/ [# _7 b& A. T  a  K- s$ {: f( M5 e8 y+ y9 V

6 I/ Z* U2 `/ x  I! l; Z【 NO.2 统计道路上的碰撞次数】
" Z3 u: I- {7 M0 x2 m, k/ v  Z, z9 g( c. d3 g' M; g
解题思路) P/ [( S: W' W
从左到右遍历,维护左侧的车的状态,有两种:& z: M' m  e8 E! Z; x
  u, O) g. L+ |( b
若干个向右行驶的: o# s# t5 T4 ?+ O
  h: C5 B. u) T) A$ x( n% B
停止
; _. ^( R) ~% v! L
8 H' c) g( U$ `0 Q, _  _6 E代码展示8 Y* `: h: \* X/ O

7 L' }6 ?6 d: c( n7 F/ Jclass Solution {
* c' b5 \2 w& E0 r6 P, o1 s1 \   public int countCollisions(String directions) {/ _8 i# R4 z% h; p8 z) ]
       int res = 0;
! i9 z$ F( D( k3 L       int S = 0, R = 0;
; F! r& \6 _) f; n5 v, q       for (char c : directions.toCharArray()) {
  E5 M, k' Q9 D5 M, @; V           if (c == 'L') {% t% V: v% f; G# c9 P+ p! L
               if (S + R == 0) {
& I' b4 N5 C& u( \: }                   continue;8 X$ }, h0 B, B
              }  }* w  n, V+ V' t2 o
               if (R > 0) {( n# \$ R- C+ ^8 z5 R
                   res += R + 1;
- x/ p3 a3 ^* P              } else {% y  O+ S- {+ {9 Z7 \1 e1 i
                   res += S;4 f& G) i1 N+ Z4 Y4 G+ L5 h. t
              }
2 D5 T& i9 \1 c/ F8 z               S = 1;4 E. Z( ?2 O! R: }
               R = 0;
: T: ?- P. L3 m+ \4 l          }
" X1 a% H; @0 y+ N1 f5 J           if (c == 'R') {
  }, x, h; x! Z7 z' X* Z               S = 0;- c+ P3 T6 x+ H" o
               R++;, c  z: p0 d; g$ R
          }' S. `  [1 S8 V' z  u8 Y
           if (c == 'S') {# ^7 V4 d, D! r2 _/ R
               res += R;% T- C4 ]: S* V# j6 S. m
               S = 1;
1 b/ C; d: R6 _; D1 j% M% F( x               R = 0;9 d0 u: E8 F4 V2 e9 c
          }* n  A. }, \  X( o8 O& |
      }1 ~6 t! G! u+ w5 t* _) w; V
       return res;
& F/ [( r0 D1 G) D' }1 m7 ^  }
3 b5 U1 J/ F, b' D9 K}
: |, m. O& t0 N9 ^) b% k6 Y" P* F' F9 q' V
( q+ i1 y  y5 {9 B
【 NO.3 射箭比赛中的最大得分】/ C- z3 a0 S0 Z4 y

; f; l0 y, U1 A7 {$ L8 O解题思路. E6 @$ l. E7 J& L' r
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。3 n' V" v' n5 z) H

: W& g" J! c1 j/ I3 @贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。/ S+ C- B" e3 Q! P( |3 Q
  X+ X$ _+ _  j) Q  T' {* v6 A' p
最后多余的箭可以放到位置 0.
0 i" A9 [6 ~. v# t8 E; X) n# I5 L+ |& v! j9 Q7 [
代码展示6 _( \! K# C" f
: V$ O9 B* Z; C. A
class Solution {
/ r4 H0 o7 h9 x/ @( `# g# D  W. R! T' N   public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {/ w% K% h3 D$ b' q" ]: w+ A9 ?
       int max = 0;
% [2 m3 v. b# y" N. |4 W       int[] res = new int[12];
8 k6 z  ~% g2 H, y9 P: K       for (int i = 0; i < (1 << 11); i++) {6 `$ u! L9 ]0 M  B% _! c
           int num = 0;
8 ~  T4 v/ y' L- G: z- c           int score = 0;
# k! ?: M) ?, h) l0 ^& s           for (int j = 0; j < 11; j++) {
1 \+ }3 S* a- S' K& h3 C1 D3 j               if ((i & (1 << j)) > 0) {, ]2 j0 v  s3 @8 r
                   num += aliceArrows[j + 1] + 1;
  z% Z3 R8 |& \, `# Q( D/ M                   score += j + 1;
' l* t2 T' B. z& o              }
1 X5 B* F% a% y          }
$ i; q& t0 X$ h; c1 E% M           if (num > numArrows) {
" L( P% g2 Y6 I2 n               continue;+ R" ~/ z3 B( p9 ~  u& c2 w* G
          }
* r0 J; G; r9 \# m) Y' R           if (max < score) {" S$ {/ j+ u9 R. M: s9 ]/ v2 k  p
               max = score;! |. P5 y5 g; j0 V# G" V8 G& K
               res[0] = numArrows - num; // 多余的箭
7 O$ @6 i! [' W- `9 k# n               for (int j = 0; j < 11; j++) {  \6 m% |! G# o$ y* n7 K
                   if ((i & (1 << j)) > 0) {
9 w6 R1 X4 [7 W' a; r                       res[j + 1] = aliceArrows[j + 1] + 1;
$ V  `2 w! U- C0 C/ \; W- b* e                  } else {
! R; w# N$ x: @. l' d2 O                       res[j + 1] = 0;5 ~' L9 M. `( M  h1 W1 P
                  }
0 r) v& Q% m* Z              }4 S( H3 H  t4 d0 Y& \
          }
" Y; ~+ {1 K: I1 s+ {6 W3 j      }
9 y+ |9 _8 Q* V* S3 c- e       return res;! B% ]/ N: K% C! e, ?/ {9 [% n
  }
9 @5 ?; J( u6 \8 H. T}( p; y4 s+ G: T% e; P; a3 l

7 K+ a& H/ N7 A4 t+ O2 @
7 Z: b% C( D; X9 _【 NO.4 由单个字符重复的最长子字符串】
# P$ \6 I6 p$ o. o( g+ v+ Q5 B
: T2 z  w3 U3 x2 G: W7 F解题思路0 F6 H/ f3 C1 T- O9 _
灵活运用 TreeSet 即可,详见注释。
( K( A9 X3 ?4 K0 H# p$ ^1 X5 P; @0 I0 _6 X
代码展示# {# d# w4 c# g

' Q# [0 z- _4 n* T, e9 i! Vclass Solution {6 z0 j6 u" H1 x. Q8 W
: \0 p8 P' t- K
   // 一个 Interval 表示一段连续的字符' N( k, v1 L0 B! Y" k
   static class Interval implements Comparable<Interval> {9 c; c8 e5 I2 e% ~. {
       int start;3 I* Q2 F; m0 |# [
       int len;2 p0 i& T8 p4 |: n- H, _
       char c;
0 w; U& Y* K' Z& d9 f$ U  C. t2 l4 M2 ]
       public Interval(int start, int len, char c) {; H8 C* Q. s6 }3 `. P
           this.start = start;- [, e: F# A, R
           this.len = len;3 b* g' f2 d& f: `( V
           this.c = c;
. K9 a9 `. z! l5 }+ J& e8 m      }
4 l% W! U) _6 L+ l2 Q4 c+ t9 X0 z) f9 \7 B/ V
       @Override
9 N: \: u1 Q7 R8 A       public int compareTo(Interval o) {: I& T- p/ P5 p5 g
           if (len != o.len) {
5 f" U- S" s: x! c: r               return len - o.len;
! Z; ^' F, C3 E# I( {          }
4 _6 n/ x' i. b9 j5 k/ j           if (start != o.start) {" x' m5 p' y5 h) j* r
               return start - o.start;
6 U9 g3 [8 [% M7 }' f3 d8 Z          }
# |% S- ~( o* [0 E, C! z2 G; N( Z/ I. H           return c - o.c;5 e/ k8 K" @  S
      }" U2 L5 {7 ]+ A4 A
  }
4 y+ O( b, A2 [4 m( U! i! V' r! e7 ?2 m6 o* l2 }  R
   public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {; _- h8 z3 A9 M& X, t4 _" e7 t
       // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理) X  |5 d: Q) u1 @. I) y- e' c
       s = "_" + s + "_";
2 t4 y3 J+ R1 e1 f$ V1 ?5 W" |       // allIntervals 按照 len 排序全部的区间3 m' `* i! e5 ]- c% [  k+ W
       TreeSet<Interval> allIntervals = new TreeSet<>();" {) L* z5 m; Y5 a# O: a2 i8 h7 Z" c
       // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序4 p. g. n+ b, @
       Map<Character, TreeSet<Interval>> intervals = new HashMap<>();
7 \' k7 {# M# `. C' v6 F' V       for (char c = 'a'; c <= 'z'; c++) {7 i, N, B$ `+ f" g: Q) ~0 D
           intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));
) X% F8 C- X& K& i      }
1 K1 b2 k+ _- f8 M8 \) {: Z       intervals.put('_', new TreeSet<>());' v8 \% |. d+ z1 n. J) B& Z5 Q

3 J! G; C2 p3 L9 g' ^7 u6 ?       // 遍历 s 维护 intervals 和 allIntervals8 T* `+ t2 n& d5 e
       int last = 0;7 G  R% z9 }/ J  i9 r" I+ l2 K( N
       for (int i = 1; i < s.length(); i++) {) K% x! ]- z1 h0 C# b+ M
           if (s.charAt(i) == s.charAt(last)) {
, s2 c, I7 V# H/ R               continue;
% O$ I1 q; s! c+ m: T7 K2 L$ J0 g          }
- K& x) b; Q2 w0 J. B           Interval interval = new Interval(last, i - last, s.charAt(last));0 D$ t6 m2 \& R6 \- p7 B
           allIntervals.add(interval);. t6 e0 S) C) Y  a' r" Y+ U
           intervals.get(s.charAt(last)).add(interval);
) P' I1 m5 o' N3 V/ o: ~1 q           last = i;$ c  j! C) ?4 q; D
      }/ D  g6 L/ P' U3 ?
       Interval interval = new Interval(last, s.length() - last, s.charAt(last));$ i: i& Q" \6 T; a# C
       allIntervals.add(interval);
7 C5 O5 j6 q8 N       intervals.get(s.charAt(last)).add(interval);
; z; O$ c5 x# ^
- g" q/ R& |1 P" D       // 每次 query 调用 maintain 维护 intervals 和 allIntervals4 _" Q- S* H" n8 g4 H8 z
       int[] res = new int[queryIndices.length];
- x( H. N4 w% V6 i, h6 L       char[] arr = s.toCharArray();
1 k4 i5 P7 w! h0 a3 t: V- t: ]       for (int i = 0; i < queryIndices.length; i++) {! [: G' l! u7 b$ s
           res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));9 g7 w/ B8 z& d$ X# w
      }/ [5 G- m* \3 h3 U0 f+ Z
       return res;. a+ b: C: Y( M2 E  C! T  s
  }
5 ?) z( W" V$ C2 Y$ D8 ?/ C
( b$ @# E; S; |0 x* P8 E6 M1 ?   // 将 arr[idx] 替换为 c
  z7 F6 T/ h0 _6 a  X6 \2 h   // 维护 allIntervals 和 intervals
. w6 u- N+ W& d  g4 _& t   // 返回单个字符的最长的子字符串长度5 _- X. Q9 l  m7 w- X0 b- \- k
   private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {. Q: p: ^( [  @  Y, O* R
       if (arr[idx] == c) {
8 ~1 c0 E5 O( Z0 I           return allIntervals.last().len;% n% w+ i0 k1 N
      }
% ~4 L0 h4 ]5 |# h- K! V) G! n* Q$ w( s6 p" H# l1 _
       // 维护原字符 arr[idx] 的 interval# h- }/ p1 w: f- M
       var treeSet = intervals.get(arr[idx]);
3 h0 W9 x, x' }/ f) ^       Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可
! ]$ r( N$ G+ a. q* p$ D       treeSet.remove(origin);
  j3 F8 P  W' t0 f; s       allIntervals.remove(origin);
2 I  F% G& _; r3 S* `7 \       if (origin.start < idx) {
6 I8 {( Z4 R3 o: C( b$ `           Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
% D, @" k7 w; s) U# Z$ X* r6 z           treeSet.add(interval);& `/ o3 q/ s1 S
           allIntervals.add(interval);+ T3 K# _0 W3 W
      }0 |1 D9 J/ b0 T' K
       if (idx + 1 < origin.start + origin.len) {
4 [5 i& W( x# j# C           Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);$ r1 p, [0 p7 I9 s1 O+ G4 i' O$ e
           treeSet.add(interval);
0 D0 i6 G: ^" U9 \$ x4 Z# l) ~           allIntervals.add(interval);
0 j* H% P# ?1 T4 |      }, C/ |0 O6 q- c" u; g

- d7 n$ g- M! r$ @" N       // 维护新字符 c 的 interval$ P5 q9 v* P' t) F
       treeSet = intervals.get(c);) H* F! O/ o2 L3 U% y
       if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接8 F# T% P0 ^/ {0 _& u  O6 c6 f3 Q
           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));
1 p( ?5 Z6 l" a0 x           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));2 N% p7 }- r7 G
           treeSet.remove(left);
  `' G# W5 c6 _1 E. [/ y" m           treeSet.remove(right);, a+ t5 w5 x4 p( U$ F3 Q
           allIntervals.remove(left);5 t0 c9 [5 {! ^& O
           allIntervals.remove(right);
- ^/ E# W: y$ m" K! R: Y           Interval interval = new Interval(left.start, left.len + right.len + 1, c);
' ~& c6 m  a. \5 q$ b* L           treeSet.add(interval);
+ d2 r( N# T$ q4 R7 N           allIntervals.add(interval);
" S# e3 A( I( v6 B6 t      } else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接
( @! Z) }# q3 ~2 F           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));
8 n% g* m. k4 e) n% Q           treeSet.remove(left);) G* s" O5 J3 S0 p2 l
           allIntervals.remove(left);
& B; a% r0 Z! i% m. N* a           Interval interval = new Interval(left.start, left.len + 1, c);! N1 K  K/ T8 u
           treeSet.add(interval);
% s! t+ U+ F1 B$ u           allIntervals.add(interval);; \0 N1 r" m0 B$ L8 h+ O6 h
      } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接  }7 z: C" C/ P# k, z
           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));8 l& N( {1 f  ~! ?' N
           treeSet.remove(right);) V9 N% R, O! z9 ~
           allIntervals.remove(right);
: P; ^. L( K" N/ P% i2 i' L           Interval interval = new Interval(idx, right.len + 1, c);5 P' ~8 i3 }- L+ N2 g. G
           treeSet.add(interval);
8 x. G% `: ~+ U0 y           allIntervals.add(interval);9 f' u; g* T) E. \
      } else { // 单独一个
" J4 |. {4 _2 p' v' l6 c! K& t! r           Interval interval = new Interval(idx, 1, c);
( \% a/ E( j1 u           treeSet.add(interval);: C5 V+ m+ k& g/ v; z. j
           allIntervals.add(interval);' I/ ~7 _5 [- X, C; K' a
      }" j: l% p- s" l4 |; X4 |6 c2 O  e; @
7 q3 ^1 y: A' e$ w7 ]: p
       arr[idx] = c;
% r- ~' {' i7 x$ s- J       return allIntervals.last().len;
6 q8 x  ~) S2 M# v. D: M  }
1 C5 t) G/ N, i) Q8 q( r}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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