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

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

上岸算法 回复:0 | 查看:2078 | 发表于 2022-1-16 21:57:01 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】. R& N: Q, b9 ^  R- G- Z" r" b4 }
解题思路9 ?: m( e. k5 D7 ^/ a) N0 ?$ A
签到题。
" {* Q, c1 Z3 o; d: R
2 `" Z5 z% F- _' D2 O4 N. f代码展示; h: s1 S7 f3 C; o, h2 k
class Solution {* R) \; X6 I0 M
   public String[] divideString(String s, int k, char fill) {4 `6 m$ q2 P4 h+ h! ^8 ~/ O
       String[] res = new String[(s.length() + k - 1) / k];
3 R0 l/ z) w$ V" N) f       for (int i = 0; i < res.length; i++) {4 Q' r+ R7 X. S, h4 w
           if (k * i + k <= s.length()) {, f5 X) b  X. _0 |3 B$ `, b' p% A
               res[i] = s.substring(k * i, k * i + k);
9 b. b/ t) z, i; Z0 l' K; R/ z          } else {
- |% ^3 z! {. x/ _               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));1 g. M' g& W6 X: u
          }
8 f" c4 j3 }/ K/ v- b      }
1 H" V( K9 K2 r       return res;
$ F& D3 Y  |; s& A! c8 w& h  }
4 u3 @4 w6 j# g; C+ a+ r5 V, r* F% o6 P" N6 t
   private String repeat(char fill, int i) {2 q2 q3 e% Y+ S3 V# c2 }$ i/ G6 Z
       StringBuilder sb = new StringBuilder();
) [) S' Y% |+ h4 C, i5 D2 C       for (; i > 0; i--) {
- ^5 V8 N6 a# T$ r& H2 H$ c0 A           sb.append(fill);
+ `' c6 ^6 h3 q1 T7 o6 _" ]- r# Q; x      }
5 T' y% \( {, A! f+ M! k4 x8 D       return sb.toString();  u$ W3 t2 A' w: @: W6 y
  }+ E: Z3 g6 k9 R; k# ?+ k
}
( q( S) U5 o- c6 ~# N9 z5 L! A* _  E! G5 y
【 NO.2 得到目标值的最少行动次数】
7 d" S. }. k; G" x& f解题思路* a5 o, l; r5 S- w# f
逆序贪心,优先用除法。0 m8 d& |) h9 ^, F" j

0 B2 Y1 \9 ]4 E2 F代码展示
$ `- ]2 h4 r/ f" \3 I6 W% Gclass Solution {
( F7 |* c- j6 D$ \2 R4 a   public int minMoves(int target, int maxDoubles) {- F8 x! f' O2 [% K- [0 J3 r' c
       if (target == 1) {
% E6 j" w( s/ y, e: M  Z6 R% ~1 U- M           return 0;+ {  }' [3 i3 a3 Q4 ?) O
      }
( u, ?2 |% x% f- [       if (maxDoubles == 0) {
& Y+ a2 k" V: I1 n( J: n7 X           return target - 1;
9 N, I" P  o- y' n" m5 N& T      }1 L; z! ], x2 z! r
       if (target % 2 == 1) {+ l+ C. e1 Z7 V4 x" j
           return minMoves(target - 1, maxDoubles) + 1;
" s  D7 l8 `/ n. F* P) L6 P! V      }. X0 W1 U0 j5 e6 Z0 z
       return minMoves(target / 2, maxDoubles - 1) + 1;
/ P  k0 D* ]2 r" @  r; k9 D  }
* `' V) l5 J5 l1 g5 Q8 B+ A}) {  t; T& W+ J, b7 q- z  O; ^/ ]3 R

  ^/ r1 B4 c' d/ K; p, S( y! H5 y【 NO.3 解决智力问题】/ b- J+ {4 T; J! o+ V" m4 R/ L
解题思路
6 d1 P+ D$ G6 F8 V' @0 K; }- g0 d动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数
. {+ {# ]4 D0 ]: |% l5 J4 }
3 f( U' r1 U( w% }2 z则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i
9 e* X8 c. _4 V7 h( ], ]; ]9 Y: e* _, |. ]$ Y3 _
使用 TreeMap 维护 forbid[j] + j 即可6 J9 ^  g" S: L1 U7 g! h2 S

, l' T; k8 q8 B- M代码展示7 V& T" _3 o2 ~
class Solution {3 d% V  \6 w) J5 @2 k
   public long mostPoints(int[][] questions) {
5 {  l6 j$ q, {/ ^8 f8 E5 f       long[] f = new long[questions.length];
" R+ [. ~  m# H9 `5 r  V/ Y       f[0] = questions[0][0];( r' a* G  ^3 t. R1 W/ i3 X
       TreeMap<Integer, Long> cand = new TreeMap<>();% z. y, d/ @8 P# E' v) F( a
       cand.put(questions[0][1], f[0]);( I0 _+ O5 ]9 c( [) ~! B+ r
       long max = 0;2 Z& L8 n; T. U0 Q" f
       for (int i = 1; i < f.length; i++) {
3 S& O# ?- a+ P: _# h           while (!cand.isEmpty() && cand.firstKey() < i) {
8 W0 P4 l! s' _& Q               var e = cand.pollFirstEntry();
, c+ D0 C6 m# i% E# Y9 D# O( K' @               max = Math.max(max, e.getValue());
3 D3 i( |, f( v7 c          }
# T* s7 z# R" T# h' V           f[i] = questions[i][0] + max;
5 Y1 m' D/ I! O/ ~  d$ P           int key = questions[i][1] + i;, B6 q/ f- p$ H/ p5 O1 Y
           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));# i0 I, t4 @2 _: |5 @9 `2 `
      }
9 l7 Z% L$ A# P& Z       return Arrays.stream(f).max().getAsLong();
* o( ]" A, H2 U' d8 C! @  }3 l: a0 {. l! s& t; U
}0 M6 o0 W$ Z# H6 ^9 H4 }: O

# P$ {: l' \7 A7 M& c. Y; d【 NO.4 同时运行 N 台电脑的最长时间】0 }1 h! x# w1 ]5 c  n: o
解题思路
" I- q! M9 r! C' ~- K二分答案,详见注释。* i; M$ H+ H; B1 p3 H. p  E; E: @, a
6 W/ Y, ^' {' }$ |
9 F7 q% k3 W$ j+ Z$ P' q
代码展示# g( `! q- f" C  w: w3 X
class Solution {
- G. I# |$ r" o   public long maxRunTime(int n, int[] batteries) {, g4 r. }( I! J' c. @$ Y
       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;
0 a# L7 ?$ U) g9 ~       while (l + 1 < r) {
1 Z6 R) y5 e7 U; I8 d+ _: |. u           long mid = (l + r) / 2;% A( ?( l& }) F6 a% Z& D
           if (check(n, batteries, mid)) {
2 \& f' }3 I: I. t' x               l = mid;
4 Z+ U, k% |$ M' {% W/ ^. V9 H          } else {% U  P: u6 _& Z" E0 s1 K+ k
               r = mid;- U) E8 x8 L4 \4 G5 G
          }
* C  ^) C% N* D8 p* g/ r      }
  M3 P# q, s; O& E* R& n( Y- ?       return check(n, batteries, r) ? r : l;2 t- J- e; |0 s- b; G' Z0 u2 U$ B% c
  }0 U) p" T. a1 z1 i/ i1 z/ \( L
' N: |( @1 x! D7 V. O% J
   // 判断电池能否供给 n 台电脑使用 time 分钟
: v* b3 o5 W" u! ~8 |: i: k3 J   // 相当于每块电池最多使用 time 分钟
; K1 d+ Y1 @2 {$ n2 _$ |   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟+ T2 z2 l; b& t- t. ]" g9 V
   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟( s9 l7 Y: ^% K% }1 \2 D: O2 n7 d
   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可
# o. ^& u/ a' y* ]7 e# p   private boolean check(int n, int[] batteries, long time) {
6 k. _8 o: W. G7 B; F; |  ]5 _  B" |       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;( X9 h9 C0 [- j  \$ z3 N7 ~
  }) g9 s) d* D9 U2 F  V( X) G
}  w, M- Q8 Z: m% L3 |; M* D% J- x
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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