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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】
! \" `' M, P6 Z解题思路
' D% ?: k& t4 c% \% w- f签到题。
, S( f& j( F. A- U. G- r- |7 T
2 ?, k! I5 |3 I7 R, ^: O代码展示
" l7 U! L+ I8 }0 ~1 D8 yclass Solution {
' r9 m8 x7 `* V, k! Q' u   public String[] divideString(String s, int k, char fill) {' x6 P" x+ l6 X# f3 H2 f- J
       String[] res = new String[(s.length() + k - 1) / k];: k! Q8 S5 ~& b
       for (int i = 0; i < res.length; i++) {' |2 V  ~1 u1 n/ @+ O+ W2 y
           if (k * i + k <= s.length()) {, A% Y6 `/ `1 @4 A( q
               res[i] = s.substring(k * i, k * i + k);* H2 x( g. `* o2 S* U/ N  D' j( t
          } else {
/ P2 u3 Q+ k  \) h4 L3 |               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));( {/ u+ m9 N: n+ }
          }
8 z2 W  q  q! I$ \& \) ?      }6 U! f( a2 F. g: U$ D
       return res;
+ I3 m8 e& l/ m, y# ]  }: T, M% Y. b. ~* \
1 Y. E. x6 E- }
   private String repeat(char fill, int i) {
% I/ R' `2 k" f3 k  N       StringBuilder sb = new StringBuilder();
8 j) p. w4 u( h0 r# A4 }) c       for (; i > 0; i--) {% U) Z2 J, |" q& ~1 v
           sb.append(fill);8 g) f5 w3 ^( D4 C: n) a4 e
      }
5 e, b. j+ Z1 B) P: h3 }9 z4 e8 Z$ Z# {3 V       return sb.toString();
  B1 m* s* W# U2 ~" W9 L, A( g  }
% P" n* t! W& U# [}
. J' ]0 C+ O  t* t8 _4 y9 c2 `1 O+ s$ l, ]0 V$ A+ l: y% \3 G
【 NO.2 得到目标值的最少行动次数】7 T# n$ [! v0 P( D+ t
解题思路
* N0 Z7 ]/ a5 W1 Q8 P3 \逆序贪心,优先用除法。* g5 z* R; ?/ e' V! i* s
4 e* L* ?5 z' ]: {1 \1 g0 {
代码展示, I: L2 g, w, s
class Solution {
8 v6 P: x9 @; C  x. I   public int minMoves(int target, int maxDoubles) {1 u- b' B% C9 c. K  U; Q2 p
       if (target == 1) {
8 F) v; L; H4 Z0 \& k1 r           return 0;* B$ c2 A/ C: S2 B9 C0 X
      }
# ~5 ]) I; b1 w4 ^# w( E3 `       if (maxDoubles == 0) {& f& b! e# T7 w  q) M
           return target - 1;; p/ g: T& k0 p6 v' X$ L
      }, w' a) r9 T. r4 U
       if (target % 2 == 1) {4 l' m, U' t! C3 F/ ]. B4 u
           return minMoves(target - 1, maxDoubles) + 1;  ?) ?# M" [9 p1 F- v
      }4 {" z, I4 ?8 n6 A
       return minMoves(target / 2, maxDoubles - 1) + 1;" A8 {8 x* S, {8 j
  }
) r1 j0 S& \' l5 Q0 ~}7 M9 ]; Y' U2 D5 z+ h4 O8 f
& ?) n2 w* s+ S
【 NO.3 解决智力问题】- I0 D" L+ P+ L* Y6 b
解题思路1 S/ O* `2 v3 r- w
动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数
) l) x. N5 J/ q& m
6 z8 h  B5 m8 o则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i( ?# t: k$ W: p: u
# y6 p  `( f' u3 X  e- Y6 _+ W: T8 ?
使用 TreeMap 维护 forbid[j] + j 即可
3 t. v$ O' G2 z; C$ [
5 h  F$ h6 F* W1 ?: f代码展示
- _- P3 t: R$ @3 g- M1 jclass Solution {
: {& k, |5 S1 W& _0 @, ?0 l4 Z   public long mostPoints(int[][] questions) {- d4 y4 D! b. D% j/ Q. M
       long[] f = new long[questions.length];2 k2 y+ H$ V/ L# d8 T
       f[0] = questions[0][0];- ]$ {9 ^+ a3 X- ?; I  i. t# _
       TreeMap<Integer, Long> cand = new TreeMap<>();
4 }, ^# c' h7 B" H       cand.put(questions[0][1], f[0]);
6 [; C5 w- f& O8 P& C       long max = 0;
7 c0 Q, D! m2 S9 h       for (int i = 1; i < f.length; i++) {( J2 X7 t' H7 i
           while (!cand.isEmpty() && cand.firstKey() < i) {
) n& t+ G5 H' a( q1 Y/ D8 ?3 [               var e = cand.pollFirstEntry();/ C5 \2 f! e" q9 e8 K* S! E" d
               max = Math.max(max, e.getValue());/ ?$ ]$ Z% @' k" @
          }" f- N1 @- H# w4 ^. b
           f[i] = questions[i][0] + max;! Y& e* h  j8 n' O: T$ x, I! M9 ]
           int key = questions[i][1] + i;2 Q" c! V; R0 e7 O1 `; t1 X8 a
           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));& A: L8 F* p( P6 |; [
      }
# w6 n0 E! O8 ~; ^0 e6 m       return Arrays.stream(f).max().getAsLong();5 |0 k1 Y' B% j3 S" Q6 ~
  }
/ x+ I" X/ b  o}
  _9 E2 d7 j( I# w/ V7 {, e5 U" O
% I5 ~. }9 K. H1 i. c% V3 l【 NO.4 同时运行 N 台电脑的最长时间】1 m: q2 E  q2 K$ l* Q6 b& g: x
解题思路! @' O5 X/ N" F1 T) J: u) p
二分答案,详见注释。. D5 b9 B) A# |7 t4 A; F8 n! S
) j7 i/ Z5 d* D* ~; ^

: c; q8 z* O- v! L代码展示
1 [  H3 u" M# u9 h3 vclass Solution {
2 J3 j+ u( p# K% u" m7 C. a# e   public long maxRunTime(int n, int[] batteries) {5 B, @. B2 V( n" o: v; w
       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;( O8 |  k+ N) n1 }( l- q/ D
       while (l + 1 < r) {
) O, b9 r. W1 k, m8 l& `5 }           long mid = (l + r) / 2;
, V, p% r$ T  d( ~/ z2 L$ N# i           if (check(n, batteries, mid)) {3 Q/ e8 m% T* G3 E6 X; K( Q& U
               l = mid;
  K7 C% A' `5 }; y: `" p# J          } else {
$ I4 |! E) f0 y, g/ w. {               r = mid;
9 i; ^% M( i+ G% |3 e5 e: }          }( E$ D' E* m& Q1 z, @5 p- b
      }* @. l3 L& F; C1 I
       return check(n, batteries, r) ? r : l;
( t, G, I8 p8 G5 ^- _3 R9 X  }
+ K. [; S; r  b2 L4 ]; A  B% b) M
: q6 e' |; N. X$ t: G   // 判断电池能否供给 n 台电脑使用 time 分钟
" C8 e5 }( o1 O2 |5 Q$ N- O- w% X   // 相当于每块电池最多使用 time 分钟
2 f8 p6 j, X- G   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟) P; G7 d% @: w9 [- u
   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟
/ T+ g9 N0 ^/ u# M- A- {4 |   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可
) u1 _' l/ [7 u$ A5 O% d- E   private boolean check(int n, int[] batteries, long time) {" b% m6 v/ t! R* o1 H
       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;
# O" D( N+ [3 x* |& v  }; w8 P( [$ _, B- C6 z  X/ `
}
( m1 e& I% K8 ^4 D+ P' g! Y
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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