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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 计算字符串的数字和】
+ ?. m+ E2 p0 [& L$ n* i) U) X; n( B1 `
解题思路' r9 t9 K+ V$ |* F0 \
签到题,循环处理即可。8 x# h! E$ f' T6 W+ X

+ J* g* @( K1 t1 ]代码展示
  S; L3 m) n5 D* Q2 W& g) u! k; b9 c
% q* r" k" Z/ h. Tclass Solution {
( p% h% a( i3 k  d# d3 }1 z% V   public String digitSum(String s, int k) {
/ W  L- B# q& K. k* r. L       while (s.length() > k) {1 @# o6 O; q, w% n
           StringBuilder builder = new StringBuilder();, ^' e' H' j3 Y4 T, l
           for (int i = 0; i < s.length(); i += k) {5 ~( u8 c$ G; S) A* F
               int sum = 0;
; `7 ?5 G5 P3 ^               for (int j = i; j < i + k && j < s.length(); j++) {# w( N& \/ ?  a$ K1 O
                   sum += s.charAt(j) - '0';
4 }, K3 g) h3 ?( k8 Z( O              }% w7 A( Y6 O- y0 n4 ~
               builder.append(sum);
* H* K7 Z( u6 M          }
- v, h4 B" K* Q& X' S5 B           s = builder.toString();/ \* Q# C5 W7 A
      }: B" z* I* _* [/ q% I, U8 L  F1 n* Y
       return s;: K6 P: I: c; f7 P$ t' ^9 g3 y/ H0 |
  }* Q- `; J3 f% z4 d! f( x$ @! y
}
# e6 d8 A/ J0 |5 l. ]) \7 A9 w* A
- I/ Z1 x7 z% ~* a, K7 c) ]  a7 A2 [) i5 B3 a, C, l" v* Z' R- T
【 NO.2 完成所有任务需要的最少轮数】
" Q- S  q' J" l5 [0 P1 X  A9 {: U0 I7 T, J! I- M
解题思路
0 Y" Z( y+ x+ x0 L8 ?9 m使用 Map 维护每种任务的数量,然后使用 dp 求解。. V% U3 q- {- K

. K% }8 G4 X8 u) n6 Ndp[i] 表示完成 i 个任务完成所需的最少轮数,于是有 dp[i] = min(dp[i-2], dp[i-3]) + 1。
# T7 E2 R& {. D* A
  j1 e7 ]* a2 k3 n代码展示. y, S0 j0 J9 x
6 U. T2 e8 z* F) J& H
class Solution {0 P2 s* ?0 e  K: I
   public int minimumRounds(int[] tasks) {
6 y' v/ I) r" F       Map<Integer, Integer> count = new HashMap<>();
/ a/ M# W2 ?) {       for (int task : tasks) {
8 b1 I# R# i' W6 [% A, z+ b" J           count.put(task, count.getOrDefault(task, 0) + 1);
' e: e: o) |% R3 B* _      }
, d4 k. ~% \0 _. m0 |- ]: j4 u: a! o' W       int res = 0;
. L: d# d, \- W5 C       int[] mem = new int[100001];8 u3 ^8 U9 }8 O, g8 P
       mem[2] = mem[3] = 1;+ x) K' ]4 c) {2 Z
       mem[4] = mem[5] = 2;# i3 q6 T# s. {% [. s9 I" s* x- F# x% F+ m
       for (var entry : count.entrySet()) {/ a6 }" r* ~; M( c
           int cnt = entry.getValue();" b( l$ I- Z9 e$ K% u
           if (cnt == 1) {: a0 _7 G7 Z2 y: T6 @% v
               return -1;
  [) p" P! X+ H. m  a: g          }
; ~! ^# Y. R6 t2 }) f' l           res += dp(cnt, mem);
/ T$ z1 p" s( m/ j8 z      }
& y1 i  n( o6 u" ~% M# b3 O- p& L       return res;+ A+ j! d+ N# v. a& R8 c- p# m
  }
0 Y) y9 G9 y3 I# |1 M1 I
/ \" b0 p" F7 ~: Z  L4 {   private int dp(int cnt, int[] mem) {" y' p* I" h- i
       if (mem[cnt] > 0) {" L, K4 V) A& U! A
           return mem[cnt];
1 O$ v/ r2 l' Q/ t& h7 ~) u5 M( `      }: s% Z" n8 d1 R4 v+ a/ w4 B1 V
       mem[cnt] = Math.min(dp(cnt - 3, mem) + 1, dp(cnt - 2, mem) + 1);! a$ d  Z, y7 Z2 l- v
       return mem[cnt];
1 ^2 a/ \! q( m  }* Y& o/ F/ p- U$ J: P/ g8 K( G
}
8 B( Q' C0 N: E6 ^/ W% r
/ m6 r* D! m6 U% [) W  r& O4 v, U  k9 B
【 NO.3 转角路径的乘积中最多能有几个尾随零】- q% a2 Q8 t  E7 t& {
7 ?; }0 F* J1 k: T6 [/ M
解题思路
' E2 o5 K6 j9 |6 Z尾随 0 的个数其实就是 MIN(因数 2 的个数, 因数 5 的个数)
, M/ q0 O$ P; q4 j) I# m1 Z- I5 _4 K* s* P# z
代码虽然很长,但大部分是重复的逻辑,详见注释。
( l6 b3 t# u5 j9 k% j
0 J8 i- W6 c2 e1 f代码展示0 v6 H( k2 i3 f# D& C9 v! t  H9 k

# Z+ x/ D7 ?4 u- ^class Solution {
% a! F) M8 `# N) n   public int maxTrailingZeros(int[][] grid) {' M, L; r! W  k0 J8 y: |* r3 |) k
       // up2 表示 grid[i][j] 开始连续往上走最多能累计到因数 2 的个数, _; F6 ^9 r" T9 |
       // up5 表示 grid[i][j] 开始连续往上走最多能累计到因数 5 的个数
( l. z: t- \! \$ A9 |- x5 R4 G( ?       int[][] up2 = new int[grid.length][grid[0].length];
3 s7 p3 T/ h$ [2 s& o8 o# X       int[][] up5 = new int[grid.length][grid[0].length];
2 c) W4 s  {: S' K6 ^8 r: b       for (int i = 0; i < grid.length; i++) {
: y0 V5 u0 p7 s           for (int j = 0; j < grid[0].length; j++) {! e0 {. v6 v4 ?7 ?
               up2[i][j] = num(grid[i][j], 2);  d3 Z* l1 k! V" x
               up5[i][j] = num(grid[i][j], 5);
+ g! i- M2 Z- P" `- W4 M4 y9 ]7 b               if (i > 0) {: B$ w+ R6 w! @8 X, i. F% D
                   up2[i][j] += up2[i - 1][j];
5 x; ]- A, p# ^$ @                   up5[i][j] += up5[i - 1][j];/ w% t$ U. s, B' l; C1 v( f/ R  Q
              }
* `; T" n, n' ~( Q& U' _          }
; g1 W1 |" x/ C7 x, V      }
+ X( P; m' P9 A       // left2 表示 grid[i][j] 开始连续往左走最多能累计到因数 2 的个数
5 U$ u  B7 j# B$ Y       // left5 表示 grid[i][j] 开始连续往左走最多能累计到因数 5 的个数( \0 W; |& g/ j
       int[][] left2 = new int[grid.length][grid[0].length];
% ]: c5 Q, D+ I       int[][] left5 = new int[grid.length][grid[0].length];7 V+ ?: }8 o% R4 t
       for (int i = 0; i < grid.length; i++) {
; x& l; V. n3 z' E, N5 t           for (int j = 0; j < grid[0].length; j++) {; V5 Y+ i9 u/ c; u( O
               left2[i][j] = num(grid[i][j], 2);
7 ?1 [+ A/ H7 Y; t4 |4 w# B               left5[i][j] = num(grid[i][j], 5);1 B9 i" E2 K+ Y, w2 u. N" x
               if (j > 0) {8 b- ?0 {" r/ h2 k, a. _
                   left2[i][j] += left2[i][j - 1];8 q7 p  a' ?9 b; ]; Z
                   left5[i][j] += left5[i][j - 1];) @, g6 Y' z! o- W8 t' S
              }
, w' C' Y6 ]5 ?  L* I          }
+ F& O( r1 m8 s# z2 [! F: Y      }% r' t9 k% I) P6 S& P2 {0 G2 k  g
       // down2 表示 grid[i][j] 开始连续往下走最多能累计到因数 2 的个数
  {& D* g2 c( R) y6 Y# N) k       // down5 表示 grid[i][j] 开始连续往下走最多能累计到因数 5 的个数
: `: r1 d9 X9 f8 A) U6 _  K       int[][] down2 = new int[grid.length][grid[0].length];8 v# }' s6 c4 q/ E
       int[][] down5 = new int[grid.length][grid[0].length];
( e: b7 u3 K7 ^6 z: \4 [       for (int i = grid.length - 1; i >= 0; i--) {( ?4 c3 Q4 y% O. [6 S5 l
           for (int j = grid[0].length - 1; j >= 0; j--) {
3 V* E' s. R0 c) R               down2[i][j] = num(grid[i][j], 2);- \- Z2 {; `, h, `5 W
               down5[i][j] = num(grid[i][j], 5);
0 A0 h8 x+ v% |2 B               if (i < grid.length - 1) {0 O! B# O3 u3 z5 E. l3 N
                   down2[i][j] += down2[i + 1][j];
3 \# f- n) t4 p$ @: H" c( ]# v                   down5[i][j] += down5[i + 1][j];
( k- [' ?8 ?7 r. x9 r6 g; \' {              }; H+ t9 B2 I$ \$ c) Z
          }
% ^% J0 u  F& Q- I      }
6 w6 I8 d; Z0 N. M9 q  G+ R7 b       // right2 表示 grid[i][j] 开始连续往右走最多能累计到因数 2 的个数% n2 Q- F" L: \
       // right5 表示 grid[i][j] 开始连续往右走最多能累计到因数 5 的个数
8 Q+ @8 j( K  s5 n# x       int[][] right2 = new int[grid.length][grid[0].length];
" B8 _  T6 ~" ~8 X; Q       int[][] right5 = new int[grid.length][grid[0].length];, h: w. v4 v3 u; X8 L! B1 q
       for (int i = grid.length - 1; i >= 0; i--) {7 a5 `. W9 c" r: p; S. M5 J& z
           for (int j = grid[0].length - 1; j >= 0; j--) {/ D4 r8 n1 ^* e) V; ]- |( z
               right2[i][j] = num(grid[i][j], 2);
  L* a) X( ~3 |# J9 F+ p               right5[i][j] = num(grid[i][j], 5);& z, G% Y. V( F) q% L1 G+ M" X
               if (j < grid[0].length - 1) {
# f3 u- n: l0 n1 ^/ z4 u4 z9 o                   right2[i][j] += right2[i][j + 1];
2 h1 |: y! m6 R                   right5[i][j] += right5[i][j + 1];
8 t6 P& a. s8 C3 x& n  T              }
5 l. o4 ^' e4 L: C6 i# o' c) {% j          }8 g. y8 ~# `: `( P; s9 x
      }
& A* V0 d* D3 c7 n
3 d$ X8 x8 |- G* l# _7 H       int res = 0;. U, M* X0 `0 N; g
       for (int i = 0; i < grid.length; i++) {, ?& r$ w! U! B) J$ ~! V0 g3 b
           for (int j = 0; j < grid[0].length; j++) {
/ N' B/ c: S3 [! i               // 有四种转角形态7 Y4 v5 k* U, n" ?
               // 1. up + left! p' R8 u+ Z7 z, T; t- N( L4 A  U
               if (i > 0) {
/ N, G2 G$ P5 Q; \$ l. R5 O                   res = Math.max(res, Math.min(up2[i - 1][j] + left2[i][j], up5[i - 1][j] + left5[i][j]));- H; l/ X4 D9 B& V9 a! n
              }
+ c  i/ P9 n% O               // 2. up + right$ H( M" ^+ r7 \/ B9 c
               if (i > 0) {; ~! C* Q% y) l$ _# G/ ^  A
                   res = Math.max(res, Math.min(up2[i - 1][j] + right2[i][j], up5[i - 1][j] + right5[i][j]));
, o) r7 o% B. k$ j$ m6 B              }9 b+ l5 I* j  Z$ X4 M
               // 3. down + left, f% \1 |$ c8 o( j* G
               if (i < grid.length - 1) {
0 ]5 |9 f0 X' I                   res = Math.max(res, Math.min(down2[i + 1][j] + left2[i][j], down5[i + 1][j] + left5[i][j]));
2 V* s0 x8 E% X- f              }
& h% G9 l# ]8 q6 c7 j7 K               // 4. down + right; g! d/ k5 f' N7 d8 g7 b
               if (i < grid.length - 1) {  i7 V% y( v7 I7 Q' v4 s0 T
                   res = Math.max(res, Math.min(down2[i + 1][j] + right2[i][j], down5[i + 1][j] + right5[i][j]));
& L/ k1 f8 X/ E$ Y# d# S              }1 `$ U, F6 J$ g$ L2 Y- \  S2 Z
               // 不转角4 ~4 i% G8 q# Q( E: z. N
               // 5. up/down/left/right
8 |5 q& A2 P: X& P. M! J               res = Math.max(res, Math.min(up2[i][j], up5[i][j]));9 X0 o3 H8 \  ]3 O" p5 p
               res = Math.max(res, Math.min(down2[i][j], down5[i][j]));
7 k6 N% U. l" l2 q& C               res = Math.max(res, Math.min(left2[i][j], left5[i][j]));1 R/ u7 ^6 z* m: K2 q
               res = Math.max(res, Math.min(right2[i][j], right5[i][j]));; |. r2 w. m, Y1 ?
          }& ?) w# [2 a6 {- r0 o+ q. |
      }$ D9 y8 M$ ?7 Q6 |' Y
       return res;4 J2 v# F9 Q! N
  }
4 |; w, E7 Q" P- ^5 K0 Z" E6 H6 p- A) I# T, a
   private int num(int x, int y) {$ h4 [! f- y" M# b  C5 ]/ e' Z
       int res = 0;
5 Q8 j7 _4 A# S* e       while (x % y == 0) {
8 [0 ]) C! Q1 `: P' s7 q$ _& x           res++;
3 c" }. x2 ^7 n: z! H1 f4 Q           x /= y;
+ }/ l" t- O( t1 Q      }' M) {4 g( P. n& i
       return res;
5 ]$ [( t: @" {8 n  }- b0 y8 e% k' {8 U% t
}
3 j4 g! I& R3 `3 t6 b0 P) z8 p# {% y8 b7 X$ F% |# {
【 NO.4 相邻字符不同的最长路径】/ z  Y" b' ?, i$ V2 h2 D

9 A& q* L' Z/ U# v* B0 C* D+ i+ e2 N' l解题思路+ P0 f1 v0 u1 z0 Z6 w5 A
求出每个节点向下走能得到的最长路径,在每个节点的所有子节点中,挑出最长的和次长的连接,可以得到经过当前节点的最长路径。3 N' g# r  c# }% U/ _
! W9 {+ D; G3 x1 z
代码展示
( ~# H1 T4 A, d+ w& n! r4 J+ h0 W+ A7 m0 z$ a
class Solution {- _( X* z/ t% P% E: a, O$ Z) x- K0 O
   int res;" {$ w6 E. z* `; d  M0 o7 F3 ?5 T! Q

3 |+ o% w0 x2 U' Y+ W   public int longestPath(int[] parent, String s) {* @) U/ C- m8 }  U4 _4 u7 ?
       Map<Integer, List<Integer>> children = new HashMap<>();: i$ r' }8 Z( j0 y9 V
       for (int i = 0; i < parent.length; i++) {
: {1 o, N) ^2 o- M8 [& l1 f. ^8 o! R           if (parent[i] != -1) {
6 q6 r4 u6 S  Q' S3 n( u               if (!children.containsKey(parent[i])) {. L: Z7 l' D" [
                   children.put(parent[i], new ArrayList<>());
6 n% N7 x  l) M              }3 u# S9 C" y% D1 I7 P. f
               children.get(parent[i]).add(i);, |! U, J! ~+ u2 j+ K1 y
          }
6 \+ n. T1 ]' X; t8 K2 g      }
# W( ?! b; L5 H, j2 J4 ?$ R! c4 y4 J) Q8 R5 ~6 |
       int[] maxLength = new int[parent.length];
+ k8 y3 B7 e# C& O0 {       res = 1;( }  f' w" y9 g0 E3 M% o9 k% n/ E8 Y
       dfs(0, children, maxLength, s);# d: M5 }1 I- L& P
       return res;6 E+ a% p7 B9 |, ?1 w
  }
, l* Q" g2 f0 s. b  w4 g2 {
* R; w2 }6 N% Z' W; V   private void dfs(int cur, Map<Integer, List<Integer>> children, int[] maxLength, String s) {9 @0 v: \. X" l5 z3 e+ v
       maxLength[cur] = 1;
* ^* }3 P6 J5 r0 @( f! N       if (!children.containsKey(cur)) {
( \* O3 i9 M/ _! s           return;
+ m+ z+ ?3 {4 K      }
) `4 W4 @1 p' p& y5 G- ^. k       var curChildren = children.get(cur);
% q0 y1 d7 Z& n" _* i& \/ ~( B       int first = 0, second = 0;) i1 h7 f' y" H! {0 |- N! |2 Y
       for (int child : curChildren) {7 \9 j6 `8 z" D- X. \5 n
           dfs(child, children, maxLength, s);: \6 x4 ?! l' m  n* B0 [
           if (s.charAt(child) != s.charAt(cur)) {! z6 g0 [* [! ^! S9 F4 G7 v
               maxLength[cur] = Math.max(maxLength[cur], maxLength[child] + 1);
2 x( ?  v. r# m+ i9 j5 U               if (maxLength[child] >= first) {: _8 \! f( R, g: E# N# _4 V! v
                   second = first;
: e4 L4 p8 Y) \( V$ e                   first = maxLength[child];+ q+ J% e+ T& S# P9 c
              } else if (maxLength[child] > second) {
  v" z. V1 x, o( x% U1 L' B$ C4 p" s                   second = maxLength[child];, y* l8 ~( Y  }7 a* ]: P' A' {
              }& ^; v( T2 [& ]9 Q2 b& H
          }
. y6 y2 N  M9 M" J      }/ M, ?( p6 u1 X
       res = Math.max(res, maxLength[cur]);: g/ g2 P! S4 e1 M  m6 S
       res = Math.max(res, first + second + 1);
. q& J+ V2 W, o- k  T( H6 i  }$ ]& j1 G2 T# ?. u, D
}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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