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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】
/ h# M, W% h2 E& ?解题思路
; A/ I& K; b: a9 J$ H% W, U" `/ p签到题。+ q4 k5 r" [! K" X
4 h! d6 {, I! A$ S% ?
代码展示  u, ]' U; h+ I5 d$ t" [
class Solution {6 D; P/ ]0 z# L
   public String[] divideString(String s, int k, char fill) {
& i' G" o2 A7 K3 W# y       String[] res = new String[(s.length() + k - 1) / k];
+ d5 b. m. F4 s0 \6 o6 V       for (int i = 0; i < res.length; i++) {, @& b9 o2 U' G9 q) o- A$ J6 R
           if (k * i + k <= s.length()) {& W9 M) M- g1 i7 ^* y( b& d
               res[i] = s.substring(k * i, k * i + k);% ]" Z  |- A. H9 i" y) Q$ `
          } else {
) E1 c' t$ T1 \( E5 K               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));
, u$ X3 y  s1 g          }
2 e+ |; I- y4 e/ X. T      }
" d% m* P! h& [$ @: |9 ]       return res;
3 d  @2 |) _7 h7 V2 h( B8 z1 H  }
; b& q2 w' N3 `* [% J) Q6 W$ {  c) t
   private String repeat(char fill, int i) {
9 R9 u' i) Y/ v8 k5 ]% w       StringBuilder sb = new StringBuilder();
" R9 Z' f; L5 d1 u. E       for (; i > 0; i--) {2 t% F+ w& s' O6 I8 R
           sb.append(fill);
1 z. |$ [( n, ^7 G* A; A9 }      }: \' d  w0 J, ^3 L$ q2 _
       return sb.toString();7 c5 k  T3 N2 V* C
  }
# Y7 @% f! Q9 g, `: P1 G/ l) j}$ N9 z7 _3 z# t

, J( m4 z8 e4 I9 {9 ]/ ?: s$ i【 NO.2 得到目标值的最少行动次数】
. j. ~8 k0 R2 _8 y解题思路
  O0 b$ v5 E6 K逆序贪心,优先用除法。: J! G0 _0 O: q, K
( h9 H# z6 N6 n7 }/ ?8 p
代码展示4 j( E8 v- t  K0 s1 i* n
class Solution {1 T9 R: ^% O- R) M" J$ [6 H
   public int minMoves(int target, int maxDoubles) {
  J( q5 N5 g$ M5 u& I       if (target == 1) {
: D3 m0 i: L0 ]4 `: j           return 0;
8 J8 N: x5 Y& _' m      }
! N! D( p2 e0 F( r       if (maxDoubles == 0) {
$ q7 `* }7 b& V9 A* B           return target - 1;
- j! F) e; r8 L+ C) f      }
" D( Y1 ?4 r  W       if (target % 2 == 1) {
) W. J1 E$ c% t# B, p           return minMoves(target - 1, maxDoubles) + 1;
) w' l- b! I6 w8 \; W      }
. a; }3 S$ R) x+ P$ s* v* V       return minMoves(target / 2, maxDoubles - 1) + 1;
! |, z1 `1 ~! T/ P1 M  }+ o2 e  B9 m( }3 A
}  x0 P; k4 e& d" o7 D

, A4 n) P: w( t5 v  O% d【 NO.3 解决智力问题】' o8 K4 w6 e6 R% m: {+ B
解题思路( V& {! u% y9 k) e# _! x- d3 [
动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数% h. O) D5 w8 j- ?% @. C7 k5 L

4 H7 ]; N8 `$ j% D' P3 o9 x% ]则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i! y4 _& g  P4 f. E. \4 q9 C  L
- L- d. s7 c3 U" \
使用 TreeMap 维护 forbid[j] + j 即可! G8 b7 k$ K7 H: Q

$ x5 a) k4 [& u5 e3 i( m代码展示
) G8 e0 Q' y! e: h; H4 x9 O" t  fclass Solution {; o6 e; X- A: j1 A
   public long mostPoints(int[][] questions) {
, I1 }4 e: `. d. R4 t       long[] f = new long[questions.length];/ U& Y# F, s1 ]( B" g, f3 y, t
       f[0] = questions[0][0];
3 h7 R" ?  W+ C( F4 K4 ^       TreeMap<Integer, Long> cand = new TreeMap<>();3 G6 M2 z4 K1 A$ x( i2 I1 n+ K
       cand.put(questions[0][1], f[0]);
/ e, N" |( P- ^$ l# w       long max = 0;
4 j/ x9 u: O9 C; h0 W       for (int i = 1; i < f.length; i++) {
7 F4 L- O* O6 z: F3 }; B! e           while (!cand.isEmpty() && cand.firstKey() < i) {7 \  O, I3 }+ s
               var e = cand.pollFirstEntry();2 U) d9 ?( K- l7 c5 z/ J8 C
               max = Math.max(max, e.getValue());
" n" P. S( N; R9 `: u. {. R0 f          }
. D4 e: f. b% U2 n6 u+ Q$ n! E           f[i] = questions[i][0] + max;2 d9 l9 r8 m  v5 a4 V( |
           int key = questions[i][1] + i;5 D5 V6 W& W  @0 B
           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));
( R( A- C% v, R# C; H4 r9 {      }
& h8 H, _8 I3 {9 o* T       return Arrays.stream(f).max().getAsLong();3 e5 a, s0 Z4 ~1 V1 f& ~8 n
  }
7 v% y, m3 f1 v8 X}
6 m4 E- Y' `' d7 Q4 t' r; i9 N1 ^, p! }. u/ U0 P0 o
【 NO.4 同时运行 N 台电脑的最长时间】! Z, ^/ D* @! R$ [* p8 |
解题思路& T  E, T7 A  k1 G+ _; X" w- U
二分答案,详见注释。
& Z  T9 Z# H" X2 f7 Q/ V/ E/ p( B& V
/ }, a7 C7 V, i$ v; E: H1 z' K) D! w8 \" U
代码展示
: ~7 h; @) F) o! Y8 A$ O4 Iclass Solution {
/ E( I" }* K2 Y; l0 d" {   public long maxRunTime(int n, int[] batteries) {7 A; P! Z3 Q4 Q4 L' m
       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;  `0 N! _& K- x* ?+ @4 s4 c8 }' w
       while (l + 1 < r) {
. ?; F: z& q( A0 \  R           long mid = (l + r) / 2;* ]) K% t; j% l% I/ j; \8 x
           if (check(n, batteries, mid)) {2 V2 Y$ X5 p& P, K
               l = mid;6 m' z* {0 _6 i; g% {' M4 ]
          } else {4 X* }  \7 {& S% S$ e
               r = mid;
% z8 _" h. X% B8 W+ Q          }
' z  ^: k- n+ ]7 s" |      }4 z) E9 h2 L, y& u/ v
       return check(n, batteries, r) ? r : l;
; a' Q( d$ `) w( G' ]4 k; e2 ?  }" }; q3 u6 G% F: h+ A0 s1 V8 R
3 G8 g# V$ o: I) v  e% g: Z2 B
   // 判断电池能否供给 n 台电脑使用 time 分钟; z, S$ R4 i) y% `( w/ u- r" i8 }
   // 相当于每块电池最多使用 time 分钟
8 q2 H  E* U( L* n   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟
! S! Q8 q# p: o* n: F   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟
# D+ s! |# e7 F1 C+ w& _' h   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可
. v0 f2 M' `- k4 V1 x1 g7 a8 w   private boolean check(int n, int[] batteries, long time) {# u  L( w, H& t
       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;- E9 h9 b& W$ ]& h7 b
  }
; R/ E+ d* T5 J* \. T2 D}
* D# j0 e- E' }9 M" @- w8 w
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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