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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 将字符串拆分为若干长度为 k 的组】
( l  H; F# l; A' c解题思路
1 t- w7 L# [9 N1 O签到题。
: o! m. x9 M4 m. D4 K; z! k
5 g  T  V1 x0 W7 q  }: a代码展示
3 v5 F) L: T, L1 {1 Oclass Solution {
, ~$ y8 q$ o6 A0 v   public String[] divideString(String s, int k, char fill) {
& `2 k6 y1 B: F( s       String[] res = new String[(s.length() + k - 1) / k];6 g6 h' k$ p- o: {
       for (int i = 0; i < res.length; i++) {
5 F+ f# |8 b( e* M: ?           if (k * i + k <= s.length()) {
8 }7 u, M* e% k* D               res[i] = s.substring(k * i, k * i + k);8 U  {8 S) M7 t1 r& A
          } else {3 H1 |* v/ \) `; D" h  j
               res[i] = s.substring(k * i) + repeat(fill, k - (s.length() - k * i));
- |: j" |. r! |4 O          }6 p/ H: X6 T! O5 [4 p  c1 l
      }" j5 W" W2 R% H5 l6 y7 x
       return res;. C7 [5 t* G+ Y* U# u& R
  }0 z) Z! |3 l* f) A3 ?7 T

; [) X- g  a! T7 c9 K( {   private String repeat(char fill, int i) {
$ A6 n0 J+ w" g8 ?7 X  \' E6 C2 y       StringBuilder sb = new StringBuilder();
. T# t0 u( ~; G9 T+ C& I       for (; i > 0; i--) {; y6 i. c0 b" j
           sb.append(fill);+ L% O) h5 H- C* K) w, ~$ E
      }
/ v2 |: W. h7 o( d3 b* a       return sb.toString();
. p( @- f- w; @" c( X  }0 x' O- p5 x0 H  l$ f# ]7 j
}
2 t; j. [1 D# T6 o# I. c6 @1 Z. w4 t+ |+ R8 o8 Z, L
【 NO.2 得到目标值的最少行动次数】& U; M/ O" w+ n  ]& K, W
解题思路
5 B7 ^! T9 ^" `* I逆序贪心,优先用除法。/ F  V9 q8 g$ [" b8 X

( V! ], S/ Z2 H: V7 z6 M代码展示
7 S- h/ g/ e* {5 N, ~class Solution {7 b& e9 u6 Z/ J% T- z; v1 t  u  X- `
   public int minMoves(int target, int maxDoubles) {
6 B0 t2 H$ T6 R% {% A: X6 I9 @: K5 V       if (target == 1) {
' B2 \3 Y) P# d/ W  _           return 0;. @% l- {& J+ Q7 U' c3 }
      }, L) e- u. f+ s8 @: F5 l6 f' p) C
       if (maxDoubles == 0) {" {/ e: L4 T- s* S% |5 a
           return target - 1;
" b- Q/ R# C7 h) t      }
+ W" F& i# [, f. ?2 z/ i       if (target % 2 == 1) {
+ C; e4 ?; t1 [           return minMoves(target - 1, maxDoubles) + 1;
2 [* _8 v$ n/ u* j9 l      }" w/ G6 @8 H# D0 b& D
       return minMoves(target / 2, maxDoubles - 1) + 1;
) y# a. Y7 z4 F, P' x  }! X% x+ k* ?# j5 O) J" G% N: Q
}9 R- Q# N; t6 l. e  s; Q2 o
& Q7 X! i' J$ Y7 p0 i! R
【 NO.3 解决智力问题】
( ~* Z& m) C* J! x% ^. T解题思路- e+ C6 f8 m( D5 `. {
动态规划,定义状态 f[i] 表示解决问题 i 时,前 i 个问题最多得到的分数% a% G( a5 s$ N  I. v7 U
7 k4 e0 z3 u0 f7 g
则有状态转移方程 f[i] = max(f[j]) + score[i], 其中 j 满足 forbid[j] + j < i
: x4 {: n7 e, \1 N  r: q7 M* Q/ ^  r
使用 TreeMap 维护 forbid[j] + j 即可
/ [2 c7 v( Z3 q- G3 [1 J5 `7 b
; _* T& o5 c' v  e代码展示, |* K  L0 w- o5 N
class Solution {: @  [% z0 `5 _6 ^
   public long mostPoints(int[][] questions) {
8 ?: [9 }* Y6 c" T       long[] f = new long[questions.length];
( ?, A9 I* j/ b1 j       f[0] = questions[0][0];( N+ J8 ]" w2 N; `# E0 A
       TreeMap<Integer, Long> cand = new TreeMap<>();
% ]9 J$ T- ~3 s       cand.put(questions[0][1], f[0]);8 c1 }3 I4 m! x8 L& T
       long max = 0;
" _" R: n0 x( c: V  k       for (int i = 1; i < f.length; i++) {
- r# l0 _* X4 e           while (!cand.isEmpty() && cand.firstKey() < i) {
+ _9 k8 }( \1 `) P" @               var e = cand.pollFirstEntry();
8 C' ^; G/ z$ _' F& N4 _& o$ {               max = Math.max(max, e.getValue());
2 M1 Y- |6 W+ G: @1 Y& K          }
% A0 x3 O. Y7 K% M3 ^  I           f[i] = questions[i][0] + max;2 F  [% v* ^$ X9 d
           int key = questions[i][1] + i;
3 m& K) T, f  o8 t           cand.put(key, Math.max(cand.getOrDefault(key, 0L), f[i]));
8 p, m8 O  F( J2 {      }: u- t- M, C/ |. A: {: _. d
       return Arrays.stream(f).max().getAsLong();
$ ?: J/ l2 _; w2 j. T2 Q  }
/ z, Z2 f' H; S: `( u) C) j1 C}$ M3 C- f7 ~) ^# {3 h( H6 q2 q

7 y$ |: A7 y  ?4 u【 NO.4 同时运行 N 台电脑的最长时间】
* \1 G, p& K% T& P+ v' @5 d解题思路! V( m" L: Y: U  x: S: Y
二分答案,详见注释。
" u8 y1 D; H+ c& F2 T: A
5 R1 p+ J  U" }/ \7 R: I8 d- m: D- ?1 r% `# D& J0 D
代码展示6 l. }8 {0 M( e, R
class Solution {
5 L6 y+ z; r4 I) w8 S; U   public long maxRunTime(int n, int[] batteries) {5 a% _( n: @3 m# ^* a6 t( `
       long l = 1, r = Arrays.stream(batteries).mapToLong(i -> i).sum() / n;; Q8 y1 m# a: z0 n/ V  F( `5 l6 a
       while (l + 1 < r) {
5 \* H7 I3 @) U: Q( K% X! T           long mid = (l + r) / 2;
1 c% E3 x' |( d           if (check(n, batteries, mid)) {
7 v: p  f, |! `" W               l = mid;
% B' x  {/ w  L3 F: Y8 Y. e2 T5 F3 O          } else {
0 J" Y! S8 h6 A3 F5 D/ f               r = mid;
9 j! k% O! D* o  Y7 C          }! k/ b9 l. w1 H6 _
      }. ]6 ?  r8 ?0 X' g; i# T
       return check(n, batteries, r) ? r : l;/ v+ A% @3 T' }4 ], |5 }: N
  }- G/ D7 h: O3 i- _7 \
, I; Z( L# n) D; Y( h, i4 }
   // 判断电池能否供给 n 台电脑使用 time 分钟
& L; f3 ^8 z' h/ T! Y   // 相当于每块电池最多使用 time 分钟
: W* l6 i, v( d! p0 \  y   // 如果一块电池容量小于 time 分钟,那么它需要和其他电池拼一起才能组成 time 分钟
9 V! Z9 H6 c4 h* z1 C" l/ \- G   // 如果一块电池容量多于 time 分钟,那么可以认为它将被浪费,可以认为这个电池容量只有 time 分钟
! n+ W4 a7 S( G; j5 E   // 因为换电池是不消耗时间的,所以只需检查电池容量之和是否达到了 time * n 即可* v4 m5 q- R: K6 y6 d
   private boolean check(int n, int[] batteries, long time) {( T, @/ e1 d( m' H- g/ Y2 Q' g
       return Arrays.stream(batteries).mapToLong(i -> Math.min((long) i, time)).sum() >= n * time;
1 l; {* ?+ ]& F1 M6 F: \4 h  }
6 _; Z+ j' i4 Z! p; Y9 L9 O, {: D}
3 F0 T* p$ p- l
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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