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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 统计数组中峰和谷的数量】
- w, ~# j$ V! x) C; i# h3 M' T+ A- ^# D- D3 I
解题思路
) v2 G5 ]* E9 M5 @9 O: O先去重,再统计。
, G1 x, s9 P; _) D
7 v9 E! K2 h- r. {- n代码展示
- E$ j4 h9 s; G# \* b5 e# f, e) a( `0 A5 V8 K1 {' S  a6 e
class Solution {
9 Y. r5 m3 P1 P% o5 u   public int countHillValley(int[] nums) {6 M* i- C5 w; M: |
       int len = 1;
. X$ v& T5 e) ~: \5 R( ^       for (int i = 1; i < nums.length; i++) {& G4 a3 a2 w* p/ Z" S' C+ P+ ^
           if (nums[i] != nums[len - 1]) {0 k+ e% \) x/ z
               nums[len] = nums[i];
) C- L1 @2 M1 c4 ]1 m. Z7 N7 R; O& m               len++;  H" H1 C" h2 u0 K9 m5 i' `5 ^
          }" |; i% z: D6 L$ t/ _4 f  @9 c
      }' L1 F- S4 U  `
       int res = 0;
, E. P5 {  {! [) W! T       for (int i = 1; i < len - 1; i++) {* f( o& T9 }9 e% u9 G/ y" \
           if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {4 H' M/ i) s" E+ n+ ?- K" h
               res++;# i9 q# j. Q" I, Q& u
          }7 ~, Z1 l4 i& }" T: |7 j; f' Z+ F* b
      }$ Q: I. _6 z% \( [' B
       return res;
7 w' E1 j0 B+ e8 n: G( x  }
1 ]/ o2 q5 \$ ?  i}8 m) A; {: I' A: U3 m. H$ }
1 i8 t, T1 M* O+ F4 c
( y/ l- u% {" m, U2 P/ Z
【 NO.2 统计道路上的碰撞次数】1 p8 `/ f9 ~' P2 I& H3 K3 _/ P: d

& `7 M: y5 C% z, g/ P+ A# k解题思路6 L8 _/ H: J. W- H) L, {
从左到右遍历,维护左侧的车的状态,有两种:2 \) D' s( V8 I% d, Y$ {8 j
3 _4 j  x! z7 q: d
若干个向右行驶的5 Y$ Y* `6 r+ q: t+ Q5 N. M5 N& Z
1 D! v; L# r& t5 U" i9 Y
停止
/ A* f* ?1 Y9 o
# Y" }& }1 L) r代码展示
, o2 p5 S+ {3 ?# c3 n5 l/ ?8 a; a6 J- _  b7 h: Q
class Solution {
8 Y! `# R. f6 @& C) z   public int countCollisions(String directions) {
. X: w+ ?: z7 T2 }7 ?' f       int res = 0;3 i# v& }  W' q8 }
       int S = 0, R = 0;
+ J: d- G2 Y4 P) R7 F: E% \/ h       for (char c : directions.toCharArray()) {- _; ^- z+ p( N; ]9 K
           if (c == 'L') {: C1 |4 F( A: q5 _$ N+ ]1 m
               if (S + R == 0) {* K) E+ @% ^! `3 a0 A
                   continue;
* Y. Y5 E( A) [+ t( W              }
& R" m% [, |' z- o) Q               if (R > 0) {
' t0 _9 i/ I& @0 A                   res += R + 1;
2 j7 G9 l4 P' y% d- A+ t, X0 k              } else {
5 u5 L- m+ Z# K3 B+ C5 W. n                   res += S;: X4 w+ S7 ]  t
              }, f9 Q2 m5 S  z& ^
               S = 1;7 C6 K8 |; u! T8 l
               R = 0;
! C/ u! S; }7 f. s8 j          }
0 j: Q  G# N+ `5 h5 B           if (c == 'R') {/ f1 ~4 ^1 ?: ]  L! A. o" D+ s
               S = 0;
: w$ A9 |3 v4 V! g               R++;
# v% a" f4 s4 {4 e8 `# u% P          }" i* Z) k! B% r% _: Z- ^
           if (c == 'S') {. E2 {. r& x' o3 u) N0 D. x7 Y8 b
               res += R;- ~9 U+ K, A6 U- c
               S = 1;
( D# g& q. i. S/ X7 K3 Y* L               R = 0;1 P$ M. Z7 S3 A1 {/ m2 v$ h& U# _. G
          }
3 \5 V( o+ v" u8 f: ]" u      }
( [8 @: L* n# _: R       return res;0 ^" L6 ^0 @% y# [* e  h8 C
  }" L4 p- c  v# x& ~4 ^
}- x+ @8 T) }% }, m+ T* @5 ^2 V; O
  n' C" L& Y; F

" y( u- H- \. F$ M8 {+ w3 X【 NO.3 射箭比赛中的最大得分】5 u8 i1 g0 i3 ^1 h
' B1 c' x! a& Z0 b7 \! f" ~
解题思路( i2 P- k: ?6 c3 h- v" p7 y  U
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
$ s% e$ F" r. d, O1 B! S. r/ J" n. c4 r: [* ?1 _% w
贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
5 `- [& y, l' N. N' ~. [
# Q9 W! b% l* v$ v最后多余的箭可以放到位置 0.
. p( s9 C* H8 p6 w( h3 Q4 W# ^/ v
代码展示- ^) k0 r) w0 m4 M  d( ~7 Q5 S

; h' H- L( p1 \9 iclass Solution {
- d+ _! u& V! c8 Z8 X$ Y   public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {6 a6 t. o- H: k6 i. g
       int max = 0;4 O6 U5 L: Z5 b0 s$ p# r: x5 D
       int[] res = new int[12];
9 l4 y2 \2 q5 l4 o       for (int i = 0; i < (1 << 11); i++) {
8 R# C" A2 @  p( b3 [           int num = 0;0 l. P+ _, ^- t4 }* [
           int score = 0;) ^) H( T- z, g( g) V
           for (int j = 0; j < 11; j++) {( E% K4 m3 {( h2 |4 }
               if ((i & (1 << j)) > 0) {
- R; }* o; S# c  Y" x                   num += aliceArrows[j + 1] + 1;" e* z1 ^/ H9 e- J7 Q3 m  [
                   score += j + 1;
% E' z# L( z. ~; }( M& a  u  [* j              }$ d6 ?0 E4 F) J1 E- l
          }
! K- x# M, x$ u% s( c2 G           if (num > numArrows) {9 p" J' w. [6 \$ @
               continue;4 N* V/ r- Z0 H0 Z/ ~! D( b4 y1 ]% n% e
          }
6 T! H6 @4 ^- `: ~2 _           if (max < score) {0 O8 ^' }' E# R7 }; k7 v
               max = score;
4 e$ s% U2 K& c7 e& T               res[0] = numArrows - num; // 多余的箭3 [% T7 V1 o5 X
               for (int j = 0; j < 11; j++) {. P% w$ J4 T, i6 q- \. y9 G
                   if ((i & (1 << j)) > 0) {. N; E2 i& b7 {+ ]0 g
                       res[j + 1] = aliceArrows[j + 1] + 1;
- n% X3 c1 w; }4 g4 f, S+ l  W5 ?                  } else {
8 X6 N: s0 x  _                       res[j + 1] = 0;: h9 n2 E" G# @% `$ [
                  }
3 d5 J9 b( D; X, q6 S7 n0 ~( @4 u              }
, I, N5 S9 n6 ?5 ?* N+ @# v          }
- T, r+ ^: {) J, G* }- i# m      }# Y9 U! V% p! U- g- q4 L1 n
       return res;
$ A' g% ~  `) A& [6 k7 H, F  }
: H8 K- W( k9 ]. `}
& f0 F' Y, ^- x4 `# G9 C$ I  C5 k; Z0 q: s5 t/ Q# K
9 g5 q- K0 J: {1 H  T
【 NO.4 由单个字符重复的最长子字符串】$ V4 g0 z; {, P

$ W$ r7 I3 h0 f- k解题思路* u7 C; g" O) O' s2 U* J
灵活运用 TreeSet 即可,详见注释。8 p- H$ u5 |1 h3 A; x" J

- `* J6 R" X/ g& _& J- H0 u代码展示% s+ g' s" f+ c  ]) N5 p. Z5 v1 h  J

6 i& B% W! D0 J  u3 z! d5 oclass Solution {8 n. y2 M- q) u- p3 @5 @

7 d1 C* o) C- @   // 一个 Interval 表示一段连续的字符
3 E7 E/ ^( k. _) i" l   static class Interval implements Comparable<Interval> {3 y% h- ]8 y  C5 c0 d7 ^
       int start;
9 L, ^: U0 l7 q3 F       int len;5 n+ z# u2 P2 X. M$ h  h
       char c;" ~# H6 W/ F& T' b6 S

# B6 |, ?0 @2 ~       public Interval(int start, int len, char c) {1 s% D4 |& x' V  E8 S4 O0 _) T4 r2 c
           this.start = start;
6 A0 z" B5 c! ]. d           this.len = len;
7 n8 P# Y3 b5 d" d  k& R. e% p           this.c = c;& S6 W' @/ k( K( q6 A$ H5 Q' A. q
      }
5 j+ U# p/ A) c* P$ O
% q, @1 i: ^$ y' v( B. H% s9 Y       @Override+ d  P- }- u! L! f3 G
       public int compareTo(Interval o) {. i9 ^- @& |' U" a, p' W5 z
           if (len != o.len) {
: E# D8 _  Z! O( U               return len - o.len;
3 ]: P6 C4 {  `) @          }& P" f: y- j0 L5 ?5 \
           if (start != o.start) {
$ i+ e; `0 v0 j" H7 p  ^& t' w               return start - o.start;) E0 G4 d0 h+ }
          }
3 Z! L+ ^$ O" S  v- U/ w  \& w           return c - o.c;
' V- N, I0 J$ I5 ?      }$ q5 |; x7 H) {! Y
  }
4 L6 F0 \& k. V- e, C- y1 @* s6 d" r4 g
   public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
+ ~! \  ]8 ]5 ?3 y$ u       // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理' f4 e- l' u' S' S1 |+ X- F3 t
       s = "_" + s + "_";% A( ^' E* h, p1 k/ Y
       // allIntervals 按照 len 排序全部的区间# I3 O& _$ [) _7 O: r  W; P
       TreeSet<Interval> allIntervals = new TreeSet<>();7 i" c- {2 T0 j. m# n! `) B
       // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序$ n# Q9 Y. s/ X. s4 `5 |
       Map<Character, TreeSet<Interval>> intervals = new HashMap<>();* A. _" E2 o: V' s3 u/ m) w
       for (char c = 'a'; c <= 'z'; c++) {
; ]/ ?  E$ e$ o8 {  B/ P7 R3 x           intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));0 g' q- \( I. _7 }
      }1 W8 d' Z5 W: M
       intervals.put('_', new TreeSet<>());
4 M6 V8 U. T9 F0 L7 \; H- n! ~4 Y/ m& T1 C/ U
       // 遍历 s 维护 intervals 和 allIntervals. L) g& N, h  s& E" f1 b  J
       int last = 0;
. d1 _% _, s# c+ ]2 f       for (int i = 1; i < s.length(); i++) {
4 a1 Y4 B  _( |7 T0 I" P$ @           if (s.charAt(i) == s.charAt(last)) {. F. D5 {8 Z; }. v: T
               continue;
% Y) \- b& J& P          }( p8 ?& G% x8 X( t% O
           Interval interval = new Interval(last, i - last, s.charAt(last));, A' _' x0 L. w- y
           allIntervals.add(interval);: M6 ]; n, }9 O4 h; A9 m4 o/ e# X
           intervals.get(s.charAt(last)).add(interval);
( \% W, u- a& ], t# b  m           last = i;
7 [/ ~6 s4 S8 R      }
! {1 V' P/ B$ S" L       Interval interval = new Interval(last, s.length() - last, s.charAt(last));
2 f% D, |1 x( H/ W# q3 N       allIntervals.add(interval);
/ C4 {6 x! U; t* ^1 m6 [2 f5 j       intervals.get(s.charAt(last)).add(interval);% o4 P% ]- t/ s" p
* m8 f* {$ D. I; H
       // 每次 query 调用 maintain 维护 intervals 和 allIntervals
4 @. E) w, k' g1 W* l       int[] res = new int[queryIndices.length];
: \" g# K6 \4 {1 ]) I4 w: ?* |       char[] arr = s.toCharArray();; w7 B% k9 d" n/ w; W5 R
       for (int i = 0; i < queryIndices.length; i++) {- p1 P& P. c: ^; c
           res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));6 v  s7 s4 v( n# x$ o. C. N' O
      }
( y) a8 L# L; W" s       return res;5 e* a6 E# d% I; V: s0 o) x) o
  }
4 k6 W) n! J4 h( M0 I
  w# L3 i6 I1 h! W   // 将 arr[idx] 替换为 c
2 t, S. ~5 p2 q/ {' q   // 维护 allIntervals 和 intervals
2 _% W0 H4 D+ S5 k1 a! D# ?+ A   // 返回单个字符的最长的子字符串长度
( u6 f" }2 X% [3 r2 ?   private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {- P$ l5 o' b. j  Q: ~+ t* \2 b
       if (arr[idx] == c) {; D. D: z2 H# i8 G- S" @+ i1 v
           return allIntervals.last().len;. P' O& {6 s! Q- x8 ~2 R; Z+ d
      }& b& ~& @0 B* B. K4 N
( E+ C$ F: ^1 x6 O( a" W# _$ `) J4 R
       // 维护原字符 arr[idx] 的 interval; Z& F4 I1 q9 }$ H4 x! l
       var treeSet = intervals.get(arr[idx]);- h& X  ^% v, ?: q5 j) F: v
       Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可) S2 G/ L, a+ ]* V3 L* a2 \
       treeSet.remove(origin);
; J, y9 n  p$ F' W       allIntervals.remove(origin);
& H% m+ T2 U' N       if (origin.start < idx) {
& @) ?% O/ C* ?" x# g           Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
8 ~7 j6 m0 S$ D; g$ ^; o; c           treeSet.add(interval);" c+ @! J4 x$ _) H/ `) w* [4 @$ ^) s
           allIntervals.add(interval);
8 |3 C. H0 ?" ~9 L      }
/ D" S" {* C2 t: Y4 _2 `& |       if (idx + 1 < origin.start + origin.len) {$ C# \: P3 Z; ~8 g" @2 V
           Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);
8 T' n7 a# |4 a           treeSet.add(interval);
. Y* m  K# _, {! B% R           allIntervals.add(interval);! W/ `9 B8 c+ r/ ~. M0 H- E5 d3 ^
      }
" ~# H2 V" u% ]3 ~- F/ R) ~! c
! B% A* V8 }* s5 e: B, u$ |       // 维护新字符 c 的 interval6 O1 [: g" Q' ~' x, S8 e4 b
       treeSet = intervals.get(c);
. c3 ~0 f( G' M% I# b% [       if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接
  o  a; l0 _4 }. p3 u( B0 _  G           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));( D% u. b  m! [/ e" h6 l
           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));/ O0 [* U$ b% |- b! o& y5 B1 g: N
           treeSet.remove(left);4 N$ F5 ]4 ~4 O2 t$ @
           treeSet.remove(right);
/ ?$ K5 g+ ?$ F" w3 Z, _           allIntervals.remove(left);- `8 h0 S3 x" O& o
           allIntervals.remove(right);+ V% p# F0 A4 `5 s1 O+ o5 n' H
           Interval interval = new Interval(left.start, left.len + right.len + 1, c);4 f; |% j7 L8 M: p2 L( k
           treeSet.add(interval);: \$ }1 e, d- T, A% n% r2 k; W
           allIntervals.add(interval);
+ ]& |( m" w; q* o) l" J: E      } else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接
1 b: o" B, u3 H           Interval left = treeSet.floor(new Interval(idx - 1, 0, c));. w  v3 P+ `1 g5 Y
           treeSet.remove(left);
9 ?) {6 y9 c+ M           allIntervals.remove(left);" w* G9 M$ w3 W6 B' ~
           Interval interval = new Interval(left.start, left.len + 1, c);6 F7 V* d  ~. _
           treeSet.add(interval);, I  w! Z, }; m* K; E7 j7 v
           allIntervals.add(interval);
- y- ^$ y) M* S9 g      } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接: S( _5 b8 S! H/ [8 L3 C5 B
           Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));' I$ Y% X" T/ ^: `& e/ P5 B, S
           treeSet.remove(right);
! f/ Q3 o& i( O: W; j( a           allIntervals.remove(right);" q* E- j! B: k8 ]
           Interval interval = new Interval(idx, right.len + 1, c);
- u! w8 u3 E/ w9 \( b, ]0 D           treeSet.add(interval);
$ [, b6 Z% o" {6 A4 a+ V           allIntervals.add(interval);
8 u2 }) W  v' k' b      } else { // 单独一个
) t; [* Z0 L8 e" r2 S' r5 a           Interval interval = new Interval(idx, 1, c);
4 D' F- V. N) U4 x           treeSet.add(interval);
9 j. w+ A* K- P; }6 j) v           allIntervals.add(interval);
2 S: }1 W: p8 T1 D      }
9 i6 W6 B' f" M+ s. i) s9 v: R
$ {7 \  r6 H% ^5 i) p# ?       arr[idx] = c;
8 `8 `/ `# i% r7 \9 T' e: e3 A       return allIntervals.last().len;' K" R, |! c! C. a- t) C4 @: |
  }
2 q% J5 Z0 I5 Q0 X# i8 i4 U- w}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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