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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】/ \3 d! H0 P( n! [0 M7 M4 d
解题思路
) {" ~, s; W3 o8 i( g/ @签到题。: q1 H! d9 c3 c# e* O0 Q

9 f/ d8 ~# k; i. C. s, `/ D代码展示# t. `& N6 G7 W( T
class Solution {+ S9 b- M0 |! [
   public String[] divideString(String s, int k, char fill) {
8 u8 p; u2 ^' }  Y' W% G) j       String[] res = new String[(s.length() + k - 1) / k];
% N5 \& l4 o3 X, Z" l       for (int i = 0; i < res.length; i++) {6 r) j3 J5 \( e( {
           if (k * i + k <= s.length()) {
- B( N! r4 e" n! t: b8 p; |               res[i] = s.substring(k * i, k * i + k);$ V- J) x. L: i, y- l9 I
          } else {4 Z4 ^6 A; i; p
               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));+ o/ Z7 ^* J( U7 g; w9 p
          }
1 w* {9 J/ X5 M0 f+ w7 o      }
2 k$ V/ _5 [1 ?4 D# G, G' B       return res;! X; \, J; Q- e& t, ?4 d: M; ^
  }
/ j8 U% M0 u2 f" d2 {# t- t6 ?& Z1 C6 j9 {
   private String repeat(char fill, int i) {
7 r8 |; A# t9 O1 F/ T9 f0 V* e       StringBuilder sb = new StringBuilder();( x0 h0 ]" J, D1 X  M3 j$ \" E, k
       for (; i > 0; i--) {2 B  O, R$ f6 Y) {: r  S) r, |* J
           sb.append(fill);
$ p2 w4 x+ [( T0 H2 z      }4 e7 b1 S) L3 D* d( \  F9 D
       return sb.toString();
. p% S$ d0 x, i5 Z/ |  }: w' n4 P4 U& E" A
}4 T8 N2 {" Y0 w! y

7 L. H9 ^6 O/ s: |3 }* u. Y3 y【 NO.2 得到目标值的最少行动次数】
' K) ~/ Y9 V: N. y. |- [6 g解题思路
  _5 t$ t4 X9 f& ~3 K$ b3 E  E逆序贪心,优先用除法。( q& O( O( \" V9 ?* P5 \6 C
; _5 z( X: k$ w( \/ `& p& ]6 U
代码展示) j; M8 X" |) k4 ~6 g; _( H; v3 d
class Solution {
# t0 h* ?2 \) x$ m# P$ K7 T. d  ]& Z, z   public int minMoves(int target, int maxDoubles) {
1 \) x2 F; u0 p/ ~" a% W' [; ~$ a       if (target == 1) {
: p1 i+ w( e3 h/ P( v' C           return 0;- L" R. L7 M  Q
      }
( h) e1 U- ]; B# U4 A% ?9 w# }       if (maxDoubles == 0) {
2 k! ~( Z7 \. R" T. H* B& m9 z- G3 C           return target - 1;
# f6 e9 Z# M0 |+ o. M/ |2 t$ A      }
" A% H. u' z( Q4 @4 c. M* q  C       if (target % 2 == 1) {
5 T9 v/ l8 k) h; z% c           return minMoves(target - 1, maxDoubles) + 1;
/ s, l2 K* t/ m) ?/ F# u, y      }
" \6 {, V# J# u6 F& ]9 ]  r5 G       return minMoves(target / 2, maxDoubles - 1) + 1;8 _4 {1 T+ U2 V+ \% r9 `
  }- ~# M* K$ l3 N; E! W# S
}
% \. L) x2 F3 w( M/ H+ H* I8 E
# {; |2 _+ G! P: D7 E# R7 n【 NO.3 解决智力问题】
5 U% t2 g" v" `; M解题思路& v* s6 A3 v2 P% c. J* g6 E: ^
动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数
8 u9 Z5 n2 K; m% A* K
6 _3 q2 P3 `9 U则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i
: x" M! M3 E% O6 g2 S
- C0 p# d8 ?9 @" d6 X使用 TreeMap 维护 forbid[j] + j 即可* O5 U6 q* W" t; n3 u

6 e) h8 x: i# z' H代码展示! h" g, I" j7 Z, x+ l! ^+ z
class Solution {
5 A' Q7 B' {4 d' D& ^9 O0 k   public long mostPoints(int[][] questions) {
7 q: p! u. {2 z2 |) x       long[] f = new long[questions.length];
& K1 v7 d5 P) I  o& i+ v, p' {       f[0] = questions[0][0];
9 J4 m! I) S5 e& [       TreeMap<Integer, Long> cand = new TreeMap<>();  m4 I) K" r. J# `( O
       cand.put(questions[0][1], f[0]);
: E% v% u; s; G. S' a- C% S       long max = 0;
) T5 ~% w2 G' I       for (int i = 1; i < f.length; i++) {0 j0 x$ t, \/ f3 i1 r
           while (!cand.isEmpty() && cand.firstKey() < i) {# N4 d* Q/ D  K, L3 M3 r
               var e = cand.pollFirstEntry();$ ^; u( M- g2 X4 }8 S( Q' \6 ?
               max = Math.max(max, e.getValue());
- K- Y) V& i' c0 m2 R5 h          }' v/ k% o- f9 P% g) I$ L
           f[i] = questions[i][0] + max;
: S# o6 h! \+ j7 Q5 b$ L0 c           int key = questions[i][1] + i;+ V: y, e: i% r' Z/ I& o3 g
           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));9 f7 ?2 B& M# ^& x% q; V) l$ K7 {! I! F
      }
; S/ k. g$ c  r8 f1 D' M       return Arrays.stream(f).max().getAsLong();1 E$ M; n! ?% I# r! X1 _
  }
4 F9 J- ~& K; K, {7 f1 b" t}
/ ?( L( D/ f/ m0 O# ?% U% [) U1 s8 }: }( s  w' |- E
【 NO.4 同时运行 N 台电脑的最长时间】7 U9 ]* h* e0 V
解题思路" i  q) r8 w$ [# O% l) H& ~
二分答案,详见注释。
8 V* ?* Q9 I; q. m7 F+ v5 t1 h. |. G" {/ g: e$ r- X9 X8 V9 u

, i; E4 }- }* s( d代码展示0 J6 E' Z! `. f
class Solution {/ O5 R) w! K: l; u
   public long maxRunTime(int n, int[] batteries) {
7 h& a$ _; [9 w( @. A" L  X       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;! L4 B) E9 @# L% e* l
       while (l + 1 < r) {
/ Y4 N/ ^! a$ ^* O' i; }1 I           long mid = (l + r) / 2;
& p& C' E$ ^& U5 d& X8 R, I0 B           if (check(n, batteries, mid)) {8 q' \' k+ {* ^& V9 t
               l = mid;0 l+ I% R7 {' h' B, K; q
          } else {, d0 O2 M; t) _& [/ j: c& T8 U- b
               r = mid;& K/ P2 n& }; m/ T1 q
          }7 [  g+ H1 C) d& V* G/ H3 t/ I( ]
      }
6 E) ^* K* q" f( m       return check(n, batteries, r) ? r : l;
$ Y: B1 Q, R. u4 j# v. p( E3 r( K6 ~  }5 M! b- l6 M3 x3 `

5 p3 t4 N& K7 y$ t9 ^* @7 }   // 判断电池能否供给 n 台电脑使用 time 分钟1 \" A+ c% c, s! e. O
   // 相当于每块电池最多使用 time 分钟- \( H& t* f; s2 S5 P9 t: E
   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟
- p2 c& G1 O: A* @3 R& G  B   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟
+ s9 }1 L4 @2 V" e6 K& Q   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可
% i* F( ^' S- p! }   private boolean check(int n, int[] batteries, long time) {3 w/ X5 N( u- P+ o. y
       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;
7 T+ t7 C1 c9 J8 s4 v  }
8 o* y6 J$ x0 T, s, s% F}
# a  l6 ~4 K3 f9 G
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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