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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】; v4 }7 Z8 y0 N' r& c: X8 n9 s
解题思路
$ ?- n  k( \1 ^) @签到题。
* f- B; J7 C9 Z, W
4 \* p) p$ u8 g9 C% ?代码展示$ q4 D4 X% B3 P3 K- o
class Solution {
9 l) L; q2 f1 e% P   public String[] divideString(String s, int k, char fill) {
' R( O; ?" Z1 M' T3 D; M4 J2 T% x       String[] res = new String[(s.length() + k - 1) / k];
3 O8 Z, r8 e. R& M9 W       for (int i = 0; i < res.length; i++) {
; s* b/ o5 Q" o4 A6 F           if (k * i + k <= s.length()) {
; c/ g# K# s# _' N/ u               res[i] = s.substring(k * i, k * i + k);
7 k) S2 |, b1 _1 j1 j' ?5 [5 l( p, Z0 G          } else {3 a8 F. ?4 @  A# Y
               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));
% F. ?" R' I8 I8 ~- l/ h8 H/ m1 y          }
( C% _) f% D' Q9 V+ r5 H      }9 G& k: x0 R/ T, Y
       return res;
" w7 V$ N- p/ J5 T' e; b( s  }
, O. S3 A  b3 v4 \3 G# S  o" z
) K9 b1 j% f7 \+ I1 h   private String repeat(char fill, int i) {/ a9 |* p$ a1 p8 \( I. \5 ?
       StringBuilder sb = new StringBuilder();
6 B0 N3 t* r) \       for (; i > 0; i--) {$ J, m  |' a( G8 _; o6 \
           sb.append(fill);0 A3 p3 B; k" U; P* w
      }
+ B5 E( Y6 A/ [# Q# Z) b5 n# h       return sb.toString();: a/ v) x, r* |7 I: a; x- ~
  }7 I5 z# _: B  s5 w5 `' H
}2 S/ |& s1 \( S" ^+ {3 Z
( Z8 z  h  g, Q8 j/ x" L3 J
【 NO.2 得到目标值的最少行动次数】
. j# v  e4 a/ x$ X解题思路
2 d9 [. \" Q# U# ?逆序贪心,优先用除法。/ G3 T1 q% c+ y/ v
* g/ z( F" ?5 `* C
代码展示
$ H$ k0 s+ i) H  e" {class Solution {
8 a! l' j, P+ @7 f; m- S   public int minMoves(int target, int maxDoubles) {
2 _8 G3 }0 I6 k1 X       if (target == 1) {
) j; L9 N  N5 S, k8 `2 G$ ~           return 0;7 P. r, {2 E; N$ S
      }6 E0 {- q1 Z, {2 E5 k$ q
       if (maxDoubles == 0) {- ~& p2 r4 X& ?5 V
           return target - 1;# n5 R. q! L  A1 ~9 C2 q2 d  g. l0 _
      }9 W2 N5 r; Y! v# p
       if (target % 2 == 1) {
$ w- K) J- [0 z           return minMoves(target - 1, maxDoubles) + 1;
# d# p  r' ]$ D( ]; \      }
) Q! F* k, Y8 ]       return minMoves(target / 2, maxDoubles - 1) + 1;  u6 O1 n8 a; p( k; x4 o0 j' V
  }
9 x1 k8 [: _# C7 K}2 S  ~; A$ \! G. `6 y% S

$ ?) ]! I4 K; ~  `4 f6 n【 NO.3 解决智力问题】
% j* K: J# b+ T9 P' M解题思路
! g! x: L; U: q' p' |# a5 W4 ?$ [' C动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数6 E$ L" K, T/ T) L5 l- y

8 i  l& Z+ o$ |! }则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i
- J: ?7 M$ F/ z) G1 m0 A" L: W! Y+ w. ^5 ^
使用 TreeMap 维护 forbid[j] + j 即可# ^* R2 z: D% j: }3 Q

( @6 z1 M; m7 s代码展示( e& M' ?7 Y$ }- y% a  C' J! Y
class Solution {
$ Y: P# z$ [6 j+ q   public long mostPoints(int[][] questions) {6 j9 u4 }% A8 j6 H3 V. ~4 h- ]* Z
       long[] f = new long[questions.length];
" r6 J2 n8 a- p# ]  X5 r1 V       f[0] = questions[0][0];2 K/ m' C9 R; z5 f  w) s5 |9 ]' v6 C
       TreeMap<Integer, Long> cand = new TreeMap<>();
+ {- \' B- t; d! W       cand.put(questions[0][1], f[0]);
6 o8 Q, V- D( t7 V% X2 q       long max = 0;
9 t/ V* J  p* Q- c9 Q+ M       for (int i = 1; i < f.length; i++) {
$ k3 y! R' O9 r9 Q           while (!cand.isEmpty() && cand.firstKey() < i) {
1 e$ q' R1 U4 S+ X) H1 n7 C               var e = cand.pollFirstEntry();1 [# X# n; |# }# v) M
               max = Math.max(max, e.getValue());; i& q4 G* p9 f, N2 d8 [3 x
          }
8 L6 h5 Y9 t. F6 n7 w- x  j           f[i] = questions[i][0] + max;
7 @/ w" N' p% b9 ]$ q9 D/ Z& u           int key = questions[i][1] + i;
) U8 j) f0 P- T* Y6 F& Z& E           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));
5 Q! c7 T/ f0 ~1 j! Y5 [      }' n: C5 ?4 p+ Q' x: y, w/ B4 m6 ~" B
       return Arrays.stream(f).max().getAsLong();  w3 Y3 x, ^: ^
  }
8 B$ x0 V" R2 r4 A# i$ {}7 Y' S- p* U7 s( i* ]6 P
5 g: J% k9 G7 T- U7 ^5 n/ O
【 NO.4 同时运行 N 台电脑的最长时间】$ o1 B  c( F: z0 i3 v* E
解题思路
; L! ?: `9 o  b! ?  O& P1 E二分答案,详见注释。* [# `, y3 x9 ~
9 _8 u7 s, u& S: x( e! t% m# g* H
; j4 B2 O/ v# g# D
代码展示( Q( Y/ T( i/ `8 m% d( @8 l
class Solution {
. T4 N# ]4 n& m* w- ~* t9 k" j1 }   public long maxRunTime(int n, int[] batteries) {) ]7 f( u% i: C( \7 v
       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;! P! M0 u5 r9 c/ G8 i0 q5 ~
       while (l + 1 < r) {( c; n; X! h1 Y" g4 n1 j3 z
           long mid = (l + r) / 2;
# t2 ]$ x( t& [- R1 j! r           if (check(n, batteries, mid)) {
( V7 |# d1 F( p               l = mid;
4 r( Q/ R. F" N" f5 \, |          } else {
2 _# T- ]) l6 X0 `! L) V               r = mid;, z; D/ a* d4 ~( |0 B9 J& t
          }
! G. @6 V. n- J6 Y1 |      }) }2 `3 ?# P: V' s7 b/ t
       return check(n, batteries, r) ? r : l;, I% X! h4 X  b- Z0 ]6 ^
  }
6 [* Y# _) z0 Z: p. S; V4 F( R  p' Z! Y1 g( P: G1 x
   // 判断电池能否供给 n 台电脑使用 time 分钟, Q) Q/ \9 |" K9 y* I$ a, q8 g
   // 相当于每块电池最多使用 time 分钟9 X* ^7 K/ k% e3 C
   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟/ \/ P7 ~& z, d% [: C
   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟1 C- C. _% f  d4 B( x
   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可( F/ P- c  m9 Q& ?& o
   private boolean check(int n, int[] batteries, long time) {
5 }, B- N* N1 P2 O+ B/ C) A       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;) I2 ~7 V, q+ k9 t
  }
5 d  ]# o$ ~& r9 e}( H6 ~8 n" c. L
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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