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

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

上岸算法 回复:0 | 查看:2040 | 发表于 2022-4-17 17:19:24 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 计算字符串的数字和】5 H3 _2 u! L7 Q9 d! J# h! @/ V
% N( p! ^( D) G( |* M" f$ i! q
解题思路
( ^- t& r% o8 t- ]( i8 V1 K9 K签到题,循环处理即可。! K7 E2 B+ e% V2 [
# o5 Y& U- o6 m' j
代码展示
9 O* Y+ {; T0 W: J( U) S- {$ r* W2 Q5 ?& G8 C
class Solution {
$ a' s; e' W# {( r   public String digitSum(String s, int k) {
' c# u; n2 T3 R! ^       while (s.length() > k) {
6 T5 |" \& ]8 ~" [' \+ V/ R# V5 ~           StringBuilder builder = new StringBuilder();5 b/ ^' T* ]* X5 l
           for (int i = 0; i < s.length(); i += k) {4 m9 Z; W  x  N0 o! d
               int sum = 0;
3 ]" b! @' a. G9 S% ?" a6 L* Q               for (int j = i; j < i + k && j < s.length(); j++) {" f8 c( b5 ]: B5 S! `( b6 ^
                   sum += s.charAt(j) - '0';, h6 j2 i- o  c$ s
              }
3 f* n6 `" @' `: i: V  ^               builder.append(sum);
" w* l. O! F; K* X" _# J# K, [8 O          }
8 r: f3 L0 C9 R, c  m  D           s = builder.toString();! ?0 T7 M0 U' T: t# p+ E4 V) b$ Y
      }
5 U7 Y9 d4 G+ P9 N( t4 Z) V: {6 @. q       return s;
+ o) {! U1 b! z) A  }
, o3 ?5 k2 Z! I$ F7 i1 p}
4 h% p& _9 z* s( m% y( a4 n, b
  q- \: D/ r$ {5 \: ~7 E$ X  h# c" |0 n7 H/ D% y5 y5 W; l$ l# ?' c
【 NO.2 完成所有任务需要的最少轮数】
+ x1 K7 A2 Q+ h; v8 z6 M3 |& K+ a* s$ p9 U4 U$ I, p- E3 v& m% ^
解题思路
% t4 o- B( F; X; r使用 Map 维护每种任务的数量,然后使用 dp 求解。
% M/ z. h3 u$ x8 K. ]+ Z5 p
( V( l# q, `, B) J7 Xdp[i] 表示完成 i 个任务完成所需的最少轮数,于是有 dp[i] = min(dp[i-2], dp[i-3]) + 1。
( ^+ |2 m4 t3 u5 l* A1 ~% h7 W1 I5 l0 `- ~1 Z* g
代码展示8 k+ z8 _& R3 Y% u8 u+ a6 A

- t0 c: ^# P/ @class Solution {* N) F3 U' U& i
   public int minimumRounds(int[] tasks) {
3 a8 T7 J6 _% b       Map<Integer, Integer> count = new HashMap<>();) _! }- Z  a7 ~' ]2 h
       for (int task : tasks) {' ^3 J. m* n% G6 K3 I9 _
           count.put(task, count.getOrDefault(task, 0) + 1);
) E4 ?$ T9 I1 d" z1 v0 z1 s      }
. Y9 O7 Y" b" c8 ^% Z# G' d9 K1 G" O       int res = 0;+ ~! w! a& P' U' a
       int[] mem = new int[100001];% S3 U6 K/ I2 ?1 \
       mem[2] = mem[3] = 1;4 n) U5 K' b# b9 b
       mem[4] = mem[5] = 2;+ e' h  \: \% U5 G# Q
       for (var entry : count.entrySet()) {+ F$ |5 `/ `# G1 Y. I% K+ c; u1 D
           int cnt = entry.getValue();6 u: [& @( [' s4 G0 `& _  a+ T
           if (cnt == 1) {
# P* [& g& U' e& {& n8 I               return -1;
2 W: y5 j3 F2 N* n          }
% G. S# H% t9 [! H& a( p2 C           res += dp(cnt, mem);
: s9 T5 p( u  |# {  b6 h      }8 Z* H; Z: ?8 `, f* d
       return res;" f  _; |# b& X# r
  }
, n% I7 |- z( h: l' v& }  x- f; f4 s' {6 @' e
   private int dp(int cnt, int[] mem) {) @; J( r6 ~# z; z) l3 B
       if (mem[cnt] > 0) {
, M2 J. \* O. h1 x& q" ^           return mem[cnt];$ m# l- h3 R1 \* n% E, Q
      }" ?3 p3 Y2 c8 U0 e2 A+ C
       mem[cnt] = Math.min(dp(cnt - 3, mem) + 1, dp(cnt - 2, mem) + 1);$ K$ h' k- ?/ N- c  a6 o
       return mem[cnt];3 z. t- F( P* n7 |
  }
9 b7 @7 U' Z$ Z% ]0 O}
9 b8 j, d1 K& P2 W1 C$ U
; u8 H# K3 R/ k; K0 f2 j8 z" G5 v( h- e( E  O) O
【 NO.3 转角路径的乘积中最多能有几个尾随零】' G9 T; v1 u: k( M/ d  U

. I/ z& T4 N* m% |7 S" r解题思路2 R2 K0 E  f2 |/ j& O$ j" r
尾随 0 的个数其实就是 MIN(因数 2 的个数, 因数 5 的个数)& l1 D3 a' l- [7 B
) v0 H$ x+ t, I. o/ m: Y, L9 L
代码虽然很长,但大部分是重复的逻辑,详见注释。
" r  @+ W& E; T9 T  c* X2 ]
2 b$ F9 e% D. m+ e9 \6 r" |! ~9 ~+ C代码展示: i+ Q$ n8 u. U3 p
/ ]/ c) |% ~' M5 O+ P- ^3 i1 E
class Solution {
( \4 E; P/ ~. |   public int maxTrailingZeros(int[][] grid) {
7 ]6 M6 ~  r- o4 d) `       // up2 表示 grid[i][j] 开始连续往上走最多能累计到因数 2 的个数4 ]3 e( T3 L0 z
       // up5 表示 grid[i][j] 开始连续往上走最多能累计到因数 5 的个数
1 a5 o/ s. [) q+ c' r' Z9 w: F       int[][] up2 = new int[grid.length][grid[0].length];( u4 n. p2 M$ }8 A0 J- ~) h  A5 w
       int[][] up5 = new int[grid.length][grid[0].length];
0 U  ~$ w% b/ X4 w4 O       for (int i = 0; i < grid.length; i++) {; }$ ]& I) V+ I7 H
           for (int j = 0; j < grid[0].length; j++) {% t. l4 t0 K0 n5 ?7 D, H
               up2[i][j] = num(grid[i][j], 2);
# J+ |8 o; A" x% h, Y) @: I# B7 R               up5[i][j] = num(grid[i][j], 5);
( b' w" x. V8 G1 a               if (i > 0) {
/ ^* C" Q- C5 l; p: H  D9 a                   up2[i][j] += up2[i - 1][j];
8 O' ]9 i6 E# K+ j                   up5[i][j] += up5[i - 1][j];
# g7 i- x, P. }/ F6 ]              }
5 ], i3 ^! A7 u% X6 _; ^          }9 h9 C& c8 c! N, i) m
      }
7 |. M0 m& c  F3 S3 g  P) b       // left2 表示 grid[i][j] 开始连续往左走最多能累计到因数 2 的个数
% ?& ^) D$ q( {$ m9 |. a3 s' R5 D       // left5 表示 grid[i][j] 开始连续往左走最多能累计到因数 5 的个数
6 r3 y* c$ T( y, {+ h       int[][] left2 = new int[grid.length][grid[0].length];
( i! [, ?& @* H8 O       int[][] left5 = new int[grid.length][grid[0].length];- ]- |9 }$ d( D8 l7 p% G' _- T# n7 K
       for (int i = 0; i < grid.length; i++) {
7 d4 |* g9 V9 [           for (int j = 0; j < grid[0].length; j++) {
0 b5 R) p! j) A2 p" h% {               left2[i][j] = num(grid[i][j], 2);
( p3 h4 F( d) z. W4 e2 r               left5[i][j] = num(grid[i][j], 5);
" ^- N# Y/ R' o               if (j > 0) {
% c9 |6 i/ {3 `                   left2[i][j] += left2[i][j - 1];+ L' a$ g: @9 v" j1 t, @+ ?+ b* a
                   left5[i][j] += left5[i][j - 1];
- K* d; C7 q' i; ~/ \1 \9 A* D, R              }
" L6 Y$ Q$ @, t. f1 ~: Z2 F. ^. O, [          }5 R( w' y- {+ N
      }, D! v; Y9 p" r' s. v
       // down2 表示 grid[i][j] 开始连续往下走最多能累计到因数 2 的个数$ q" H6 H1 I1 J/ P' ]2 X. h
       // down5 表示 grid[i][j] 开始连续往下走最多能累计到因数 5 的个数- q6 t# D0 A' y& f: j3 |; v
       int[][] down2 = new int[grid.length][grid[0].length];! S# B% l/ L6 D8 B
       int[][] down5 = new int[grid.length][grid[0].length];
5 w) O" r) j4 f4 M. B5 ~; q3 _       for (int i = grid.length - 1; i >= 0; i--) {
6 K* H$ D2 {% |+ e4 w0 F' T4 A           for (int j = grid[0].length - 1; j >= 0; j--) {( z, B; M7 h% `/ A
               down2[i][j] = num(grid[i][j], 2);9 h+ Q' Z" ]! Y8 a
               down5[i][j] = num(grid[i][j], 5);7 X; A9 n1 E1 L+ a6 s
               if (i < grid.length - 1) {
8 ^9 Y1 x& g& K' @: G                   down2[i][j] += down2[i + 1][j];
- l* s/ _( g* d                   down5[i][j] += down5[i + 1][j];
/ U( v. `. s9 y; |0 r+ n, v              }6 `5 m: @) O/ w/ f. f# q
          }. n# T) r) h, ]/ L2 j
      }
; y; @9 @! r* i- ]$ s& v       // right2 表示 grid[i][j] 开始连续往右走最多能累计到因数 2 的个数9 J& X* O" l4 f6 [8 e
       // right5 表示 grid[i][j] 开始连续往右走最多能累计到因数 5 的个数$ N7 q& Q+ H  s
       int[][] right2 = new int[grid.length][grid[0].length];7 e' S; D# Q( V0 s' F# m' g. ^5 u
       int[][] right5 = new int[grid.length][grid[0].length];3 G2 z( \9 t- O' w6 |2 o
       for (int i = grid.length - 1; i >= 0; i--) {! E0 o2 h5 A2 l3 E% ~8 N
           for (int j = grid[0].length - 1; j >= 0; j--) {  i9 J7 Z) u( V0 @: V
               right2[i][j] = num(grid[i][j], 2);! x1 x: |! d$ L8 ^" q3 [/ G
               right5[i][j] = num(grid[i][j], 5);- k, d1 ]3 T! g7 P
               if (j < grid[0].length - 1) {
- R/ \# F& ?1 Q$ M                   right2[i][j] += right2[i][j + 1];+ J$ z; T  c! P$ k
                   right5[i][j] += right5[i][j + 1];; F- S& T- E5 S( s9 ~
              }
9 K& [$ K8 c- C1 _; K          }. k$ W& R; Q$ x2 L  c3 h/ ?  s
      }$ r9 C- q9 V6 `, O8 ]' x8 x

' y4 m( r; }/ E4 X/ J3 E       int res = 0;
2 ^* t* i; Z/ f6 G       for (int i = 0; i < grid.length; i++) {
7 K% F, e% O& Q$ {0 ^& E           for (int j = 0; j < grid[0].length; j++) {
# N; N  D- ]: d" T7 P9 S) W               // 有四种转角形态
, {' J3 y$ F: T               // 1. up + left
3 a* m" U  B2 |1 K' z5 @  e/ J2 x2 U1 i               if (i > 0) {3 {% N# `2 t8 m! k0 @  M" [2 @
                   res = Math.max(res, Math.min(up2[i - 1][j] + left2[i][j], up5[i - 1][j] + left5[i][j]));* v( o/ S6 b0 W, M/ \
              }  T) O2 ]* ]" a3 m& q0 R
               // 2. up + right; D- d$ X8 M, ~! {: E
               if (i > 0) {
1 u" l' C* w9 Z: \+ _( w                   res = Math.max(res, Math.min(up2[i - 1][j] + right2[i][j], up5[i - 1][j] + right5[i][j]));1 c( B* L9 J; c
              }5 c! a1 T6 n4 g
               // 3. down + left
) V) M  Y* |/ X! ?               if (i < grid.length - 1) {
3 y9 B- t. k( c  R1 M" _9 l, c                   res = Math.max(res, Math.min(down2[i + 1][j] + left2[i][j], down5[i + 1][j] + left5[i][j]));
) U" J. P% G9 {; W& r# z) g              }
( i  J& _  e& B* K3 u( d& C6 w& _               // 4. down + right
" J4 W; _- G, ]/ g! a+ [3 D7 t5 h               if (i < grid.length - 1) {
" s0 g0 w3 f9 x; y; s8 g; Q                   res = Math.max(res, Math.min(down2[i + 1][j] + right2[i][j], down5[i + 1][j] + right5[i][j]));9 x; C- z% `) a; ]. b( [9 f
              }# ?  s! n( ?; |
               // 不转角- \- Z! `! g3 c4 n1 B. @
               // 5. up/down/left/right5 T5 f! S8 B& R% G$ A1 q
               res = Math.max(res, Math.min(up2[i][j], up5[i][j]));
: D7 {4 L  m7 W8 `1 G6 a               res = Math.max(res, Math.min(down2[i][j], down5[i][j]));
* B9 \; _* }: h3 i               res = Math.max(res, Math.min(left2[i][j], left5[i][j]));
6 z; M' r, a5 \, R6 ~               res = Math.max(res, Math.min(right2[i][j], right5[i][j]));
+ E$ i* k( u8 M4 v3 r* K          }* o* [) d/ r6 l0 r5 W! z
      }
- v1 b9 Y7 h- A  _. Q8 F& T7 ?       return res;/ k$ Y" g. J, K% ?2 n; y( J+ o
  }
5 ?5 B3 a0 g! m' n; y" o8 D- j/ T- |. t- `! i
   private int num(int x, int y) {
$ d) u. K: x0 }+ ~( u% c       int res = 0;
8 q  _; }. ?# C       while (x % y == 0) {
9 c: W5 B8 x+ z7 A. Q7 x/ k4 l           res++;+ Y6 y0 m, l, k& c
           x /= y;' Q2 y; j' V  z8 b0 H8 P5 C+ j
      }
6 g: W% z+ x: Q( k( f- I7 d6 p       return res;9 T* u) c5 L. H% \/ e* M" Y
  }
# h# U9 o( {# U% j) l3 k) l$ Z}
- V, b5 h" |7 o% X
3 t- k. b0 h  V8 K5 e# P【 NO.4 相邻字符不同的最长路径】
/ o" y  ?% ~, S) R
& K! M& ?- @! x3 K2 l解题思路* z: |3 @; y% i& z: _: C
求出每个节点向下走能得到的最长路径,在每个节点的所有子节点中,挑出最长的和次长的连接,可以得到经过当前节点的最长路径。
+ ~' `. Z$ ]+ Q6 |% r+ {4 K. J( L+ }$ V
代码展示
- r% F& j1 `9 w2 _8 U( y$ |. A8 Y% ~! e; A$ u2 [
class Solution {' C/ X# j2 M- X* V& k1 U; R
   int res;
0 w! r! ^# s' T0 ?2 U5 U4 @. h2 `: _
   public int longestPath(int[] parent, String s) {
) K. a' I/ G3 h/ X7 e7 R       Map<Integer, List<Integer>> children = new HashMap<>();5 y$ t( J, e. h8 a5 B9 R& _
       for (int i = 0; i < parent.length; i++) {
& C9 Y0 A' y& I7 X6 K           if (parent[i] != -1) {/ W: [  N  c1 }: L
               if (!children.containsKey(parent[i])) {* ^" F. q4 z, Q2 S! @6 o3 r# n
                   children.put(parent[i], new ArrayList<>());
# O7 ?' w/ j$ x! v              }
/ T  h7 e- O! A% x$ q) G               children.get(parent[i]).add(i);8 f# ]1 p' A3 H; [1 y/ q
          }
& U) z& U6 c8 @+ \      }: z1 H( ~% e& `9 X
2 G- N8 _8 E; t1 n- L
       int[] maxLength = new int[parent.length];. N" R, v) z6 M, p
       res = 1;
* W) C9 C3 W( e. S4 t1 h3 _, ?+ U( i       dfs(0, children, maxLength, s);
+ {* I. c3 @: o. R1 t, b7 D       return res;
2 c/ e2 h  y, u! x  }
1 b" C) f: _9 C. X) p
. p7 g5 `5 f- A2 H   private void dfs(int cur, Map<Integer, List<Integer>> children, int[] maxLength, String s) {
# F- o+ f; T# ]3 y9 s5 a       maxLength[cur] = 1;
$ V1 {. W1 ?! D       if (!children.containsKey(cur)) {
2 P; a$ M9 ?- [  `           return;# E8 W$ ^, a% U1 i( w" d7 h/ L
      }
+ E' N4 D( z, s       var curChildren = children.get(cur);
7 ]# X' O% C* R$ d       int first = 0, second = 0;: j. \+ T: M# F
       for (int child : curChildren) {: F4 g; I  Q& V1 Z( n
           dfs(child, children, maxLength, s);, @0 m* j$ t! F
           if (s.charAt(child) != s.charAt(cur)) {- i( q- R& x6 B" a# R- _
               maxLength[cur] = Math.max(maxLength[cur], maxLength[child] + 1);
4 e1 }; I( v+ S5 @- Y( w               if (maxLength[child] >= first) {
4 r1 a" l( Z2 ^' x% _7 W                   second = first;! d# [1 y1 K* Q( j% x! ]$ i
                   first = maxLength[child];
0 x% ]' \  R. ]5 M& c1 Y              } else if (maxLength[child] > second) {
! ^- J) t9 c, M4 Y7 A3 l                   second = maxLength[child];
" ~, u# j$ C6 D( S              }
: E! o) x! w6 m3 _5 U8 @! P          }
. m$ Z9 u3 k* L- D0 C$ [( P9 |7 A      }
; F+ G2 d/ a- q, [9 `       res = Math.max(res, maxLength[cur]);* F5 A1 E5 l4 U/ y. X6 x& F
       res = Math.max(res, first + second + 1);
. i  D  M) M- k  }2 |- S+ b! X! U  l
}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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