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

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

上岸算法 回复:0 | 查看:2193 | 发表于 2021-12-12 22:20:14 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 环和杆】
$ r* s  r0 ^( s, i9 d& m& Q
% g7 k# d& b$ t5 o4 d/ _2 _解题思路
7 y$ B' c( |. F3 y& R  u签到题,遍历一次即可。( _# O  G6 O2 y  x9 x3 Y

9 _: h/ k$ [5 M' ?% z6 c代码展示5 V. p- q/ V  n# x6 F
0 y' S9 U3 h  X% F
class Solution {! K, p1 J$ o3 ~3 U( q
   public int countPoints(String rings) {
" y; [- j# w: O9 c, u3 C: B       boolean[][] color = new boolean[10][26];
7 I4 C1 N; `5 Y% m       for (int i = 0; i < rings.length(); i += 2) {. o. c- p, l& D4 S  {' `% q' Y% U
           color[rings.charAt(i + 1) - '0'][rings.charAt(i) - 'A'] = true;3 R. F7 @% z$ @9 H: m. h1 \9 `/ ~
      }' Y$ M3 x/ k1 g; e: F
       int result = 0;
- m( f  |2 K3 D! ]' {* q# ~. U       for (int i = 0; i < 10; i++) {" H$ }! U* Y% V& s; ^6 ~
           if (color[i]['R' - 'A'] && color[i]['G' - 'A'] && color[i]['B' - 'A']) {
: V# }* t$ M* `# q) z5 k+ J( O" T               result++;! w4 K5 L# m. L9 _" `! c7 g
          }
6 D7 l7 M: `, b2 c# @& y6 k      }
  ]9 f; o7 e3 P, a% W% f" O) E       return result;# Z& _, ]# J) q, i" ?  {
  }
4 t" B4 [5 Y# ?* \, W}
# {/ W7 ^) V" z  a* a
! s5 }1 B& r# O7 l" r【 NO.2 子数组范围和】; m' o. j4 ~" Y% o1 a* [
* f' _# F, R4 }
解题思路
1 d- S) u- W1 L+ o0 H, d枚举所有子数组即可。
% c" T! D& c! ~
) [8 |3 i, P$ S代码展示
+ U7 J( n' X& E: o: W; O' M6 Z: f& f% L3 d
class Solution {
9 I! E' f$ ?) Q+ N* u   public long subArrayRanges(int[] nums) {. ^2 L8 ?" V$ m3 O0 m, `8 S; ]7 S
       long result = 0;
+ t' n0 ^; L% i- k: j       for (int i = 0; i < nums.length; i++) {$ F7 a! p: W! p# n% W- E- D0 b/ D
           int min = nums[i];: F" B! D7 G1 f5 Z
           int max = nums[i];
. N" [5 W$ f0 F! p           for (int j = i + 1; j < nums.length; j++) {( o6 N  k$ l( J/ a; h
               min = Math.min(min, nums[j]);# d: {5 z& ?8 u
               max = Math.max(max, nums[j]);1 |2 m! N* ?! S9 ^8 b5 v9 T
               result += max - min;  P8 [8 w: D0 I. N
          }
+ y$ s1 C; J5 r% |6 {4 S8 c      }8 h7 k( s; f% e, V. {
       return result;
7 x5 ]+ f8 H' C, \5 ~  }
: w; j) `. L0 z& I8 v}3 j9 d2 w( B# F
5 {% c& O4 D' N1 r% n. G
- X* v/ I, T" k# g
【 NO.3 给植物浇水 II】
  z- Y2 }4 B. D2 x; t7 M' v4 E2 g# H) A5 {! m, |% s2 N( t
解题思路
8 ~6 }  s# J; e模拟即可。
! w# X6 M1 A" [+ i$ A- |5 G# G9 U$ i3 z7 }4 U
代码展示
$ W, Z0 ?& s  }+ O9 G# @- A1 t" ?6 m, _
class Solution {6 t3 Y4 C5 g8 `! a+ _6 x
   public int minimumRefill(int[] plants, int capacityA, int capacityB) {8 o1 u$ w% E; y* v
       int result = 0;! e7 P) r: Z3 X: w" N" I
       for (int i = 0, j = plants.length - 1, a = capacityA, b = capacityB; i <= j; i++, j--) {
4 r% y7 M( q$ q! N8 \           if (i == j) {1 L% j9 W3 H9 w& f  B
               int c = Math.max(a, b);
2 s+ w$ ^" r0 |6 M: ^" ]4 M               if (c < plants[i]) {
# r2 {+ V9 y+ b! O                   result++;
2 c; t! s& O( m              }9 V6 S  P- T: z& F5 H# ]
               break;
! E% q8 y5 N' I; D' @" L+ i5 n          }* W) U6 l1 D* q$ B0 C8 L% l
           if (a < plants[i]) {
) S! S$ ^8 W; Y5 y9 F6 U               a = capacityA;
( l+ G9 k- m5 ]4 i0 m8 b& k- y               result++;
7 E& k/ `7 j) M5 N4 X- P0 S: {          }. s) Z/ @" b3 T
           a -= plants[i];
! {+ y5 S7 \% |; n$ H7 {% {9 ?9 J           if (b < plants[j]) {3 Y) J  s  G& I# o& o4 [* R" j
               b = capacityB;
. C( @7 X3 r* P' E               result++;
& |7 P5 w: b: d# n8 H          }7 d' Z: w4 _+ x9 F6 t3 T  j
           b -= plants[j];
0 q1 M7 G, l3 Z      }6 M/ a: L: ~" x0 v
       return result;
$ {: c5 i9 Q' i4 `4 f4 |! s$ G  }
- a8 y0 |9 |6 N% G( Y}
. e- L( ]! \- y0 V8 ^  l
$ }: g* y+ h. q/ N+ H/ C: }' c$ j% K# e$ I' }9 c" g
【 NO.4 摘水果】$ ]' c1 ^9 ?( h- h$ k

: a( ?+ x" E- r, x* s解题思路3 {! o- W7 N6 A- f' W& F
我们不可能来回反复走,只会有以下四种策略:8 ]; o1 u9 I: E; c" ?

1 Q, ?( I& `1 w% `1 }从 startPos 一直往左走 k 步
- _. `; _3 V1 }# n4 \) ~: B! c7 s9 Y) Y, a! J
从 startPos 一直往右走 k 步# s: Z& A9 ^; z7 u% W. X
( D2 }) R8 [3 A& I7 L5 C" h5 V
从 startPos 往左走到某个水果位置,然后折返一直往右走,直到累计 k 步, T# d# i1 O; p& C. N3 \; G. S, i
$ ]- h0 \: g9 I+ j; p: \7 {
从 startPos 往右走到某个水果位置,然后折返一直往左走,直到累计 k 步
/ E" h" k7 i/ R# c+ m3 |
( z( N- d& }9 X. V0 K1、2 均可一次性求出来,3、4 需要枚举折返点。8 |* h0 }- `/ M' n

' s1 ^' F5 O3 R. N) X整体上计算前缀和,然后利用二分或倍增加快 3、4 的求值。& X, M/ k: [$ a5 q  ^( k
/ r$ ~6 j% A: \5 c: ~
代码展示
  D1 F" i5 n' `0 }  V6 D( P
' a1 {' |9 B/ ^8 _9 d( [class Solution {7 P" n& V) t/ P" X
   public int maxTotalFruits(int[][] fruits, int startPos, int k) {
. h( d0 V% ~, S( _) G2 E; Y       int[] preSum = new int[fruits.length];/ }7 i1 a+ O' ~* G0 k6 l7 ~' d
       preSum[0] = fruits[0][1];
# E! O7 h4 C0 D8 z+ w& V0 F9 L3 [) H       for (int i = 1; i < preSum.length; i++) {
% V, g8 m( l( d! X' w           preSum[i] = preSum[i - 1] + fruits[i][1];* ^" ~/ m) T9 \) K7 L2 S0 W) R" L
      }
5 x0 g$ P7 P" s' Y" i/ r& S+ L% T. {
       // 1. 一直往左走
1 h, ?) q- h! e3 t: H, Q( ?' e; d       // 2. 一直往右走
; ~$ X( Y; M1 x5 l$ N/ ]9 |       // 3. 往左走到某个点折返,然后一直往右走4 ?9 Z: _5 l6 n9 r
       // 4. 往右走到某个点折返,然后一直往左走
& G$ Z1 H* [& k" j, U8 \       int result = 0;8 u0 ?8 Q7 c% k; T% ~
       for (int i = 0; i < fruits.length; i++) {* R8 j* b) x2 U) M
           if (k < Math.abs(startPos - fruits[i][0])) {- g6 m. p+ g( p2 Q1 U8 Z
               continue;/ W& \7 k1 V  ^8 B
          }
4 A; b" q% r# b& S! [. N. |           // 折返点是 i
. y8 L7 T! ]0 |4 C9 q           result = Math.max(result, maxTotalFruitsStraight(fruits, preSum, i, k - Math.abs(startPos - fruits[i][0])));
, E9 x  d# T# S      }
7 n- ^8 o2 }! {1 W: j       return result;. A% r" W( y) e" ^7 Z; i4 l
  }" l9 c; r) }/ ^& A) S
- o. s. n$ ~( J' v2 ~$ e
   int maxTotalFruitsStraight(int[][] fruits, int[] preSum, int startIdx, int k) {
6 h- }/ T7 r, W( v8 E       // 1. 一直往左走
- @4 P6 l3 q* z: T       int step = 1, idx = startIdx;; Y' F; {5 p. V
       while (step > 0) {
5 x# {/ {" W0 g+ `* `/ F           if (idx - step < 0 || k < fruits[startIdx][0] - fruits[idx - step][0]) {* h" w7 w2 {0 L. u
               step /= 2;
/ z" m! F7 i$ C4 g: B$ H# q  `               continue;
; u; |3 Q/ f' ?% k. K          }" V  m8 j3 i- s( j
           idx -= step;% u$ |0 n; W+ D* _
           step *= 2;1 u& v: H- [5 G- n& D) ^! Z9 q1 X
      }$ ^" Z0 D' w. D+ W9 B2 E: ~
       int allLeft = preSum[startIdx];. Q+ p# R8 l$ F
       if (idx > 0) {
) e: m* N: L+ T. `( X9 E2 \           allLeft -= preSum[idx - 1];( d+ h- F* C3 ~5 W, k
      }" m& F3 |; o9 D: _8 W
       // 2. 一直往右走
0 W6 j3 B1 `" `1 m       step = 1;
7 r2 q5 k) Z" h  x       idx = startIdx;
2 K0 k; q* z' E6 ?- O       while (step > 0) {" V! J/ G8 q: G% E, o4 h! i
           if (idx + step >= fruits.length || k < fruits[idx + step][0] - fruits[startIdx][0]) {
1 X# E7 d" A6 V$ Q  m% I+ q  H               step /= 2;
3 o4 p2 U# V' A( t1 l               continue;) U# d5 G& L$ h7 p9 Z: X( g
          }
; K4 P1 R, B# L% U7 `  U$ S           idx += step;8 u# F" d! J2 e) a8 X% @1 h
           step *= 2;
$ C5 b$ L- J% ~' o      }
$ R; E! Z, L9 `5 Y: t1 m1 |3 C       int allRight = preSum[idx];
- i9 v& D* H! y: o' [( w& n( a       if (startIdx > 0) {
4 b9 l" V9 d9 Z" Y; j+ v/ v  l0 k           allRight -= preSum[startIdx - 1];
' C. }- Z8 ^2 j5 F" Y; ]      }
, R* [9 L1 R# t       return Math.max(allLeft, allRight);' `: Q) I" a4 b6 k- K# P
  }
2 t, d+ s1 c  g% q}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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