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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 计算字符串的数字和】
* a& R& ?) L) B0 \1 B9 y) d- \
; U' W- i+ i& u/ }5 o解题思路8 U9 E  S; C1 g2 Y! h
签到题,循环处理即可。6 Y4 \! R# Y& L7 f8 A4 w' K" W
+ n2 u' C" @: U( J
代码展示6 r5 l1 ~* P6 j0 D) u1 M! R

. f% l! h6 X/ Z  W3 Y  d5 wclass Solution {
/ H2 q' }" A$ ]# c1 n   public String digitSum(String s, int k) {
  t! m5 }; n& R       while (s.length() > k) {
# ~2 e5 p; J( O5 Y1 S           StringBuilder builder = new StringBuilder();
+ R6 E( H1 o/ R( S9 d8 {" S           for (int i = 0; i < s.length(); i += k) {) S* W& A# w& K0 m* V
               int sum = 0;# Q. l. s7 H5 @1 e
               for (int j = i; j < i + k && j < s.length(); j++) {" h; O9 I9 O; b; L7 Q+ @2 M& u" w
                   sum += s.charAt(j) - '0';% }) x5 g8 N8 r' V) R, O
              }
" b6 f" H. i) c( E; {               builder.append(sum);4 B0 [$ @' B* K& q% o2 e+ x& R
          }
/ T9 I$ V  c: F( `$ r           s = builder.toString();
6 B9 f( j$ f* d. f7 Q2 P      }& a. y1 y" D2 u; _4 [
       return s;
6 H/ _1 x# I7 Z) m+ L! E  }* n! B. C% T# z  ]
}3 n5 X, k' b9 R( S
- c) t1 ^9 Y) b: L% b

8 `9 m# t3 w3 e9 e& z1 `【 NO.2 完成所有任务需要的最少轮数】0 H) _: ?* d* z% ~# N7 E! g
8 M. ]( V9 M+ R  Y% I
解题思路
5 R, H' L6 I  k+ b( ^使用 Map 维护每种任务的数量,然后使用 dp 求解。
5 y. H" e6 n! [9 p3 k$ ~& p5 q# O# s* G: M' v) p
dp[i] 表示完成 i 个任务完成所需的最少轮数,于是有 dp[i] = min(dp[i-2], dp[i-3]) + 1。' ~9 X& Y& H, b; m6 U. {
! K2 S- U6 v# I0 Y
代码展示$ l  w. c* Z7 p

; _" k* v. K  F2 ^/ ?class Solution {' B8 H/ C( X  P4 S
   public int minimumRounds(int[] tasks) {$ x( n3 i% o  ?- @7 W3 X
       Map<Integer, Integer> count = new HashMap<>();
8 z4 [$ q. T; w  s       for (int task : tasks) {
+ o# @+ c8 y& B           count.put(task, count.getOrDefault(task, 0) + 1);
1 I* W/ y+ E5 @0 R* z" q      }
0 o1 `( z# y5 X! ^6 }( ]5 x+ h       int res = 0;; D% w/ M! ]! o8 U- N
       int[] mem = new int[100001];
* T1 _0 F0 K' u) @+ j4 V& L       mem[2] = mem[3] = 1;
; d9 D5 \4 Y2 Y       mem[4] = mem[5] = 2;
# x- C1 W; a# \* ?: M/ z6 \$ R       for (var entry : count.entrySet()) {
4 w$ X  \8 B# {& I           int cnt = entry.getValue();
' u4 \2 @1 T! g2 W. d) `7 K" X# m           if (cnt == 1) {
7 T& e# O  z% v/ m3 K1 E               return -1;
0 u6 ~- l7 P9 t* M! Q) s          }
- G, c. j8 M8 M2 M4 b           res += dp(cnt, mem);
4 A- q3 ~8 b9 V+ ?' l      }+ G- s, U& b  g$ O  l; |" M
       return res;/ J! X7 k7 O: q$ J, D+ Y3 [2 e
  }- I" T" Y3 @& s9 K3 _+ q

2 ~$ G2 e- `' S, [4 M9 @1 A/ i   private int dp(int cnt, int[] mem) {# P0 g# K7 w  Y$ C2 f* H
       if (mem[cnt] > 0) {* o0 Y/ Y9 r# a  |) S# F( o1 {
           return mem[cnt];  }$ c5 i: _8 j
      }
; q4 Q9 Y" U1 g; p       mem[cnt] = Math.min(dp(cnt - 3, mem) + 1, dp(cnt - 2, mem) + 1);# U* L/ d# v- r, h4 H
       return mem[cnt];1 O4 K$ W6 ~% a' ?* ]/ }
  }( t0 p5 ?. o! b' v0 B) Y( {
}5 M2 U$ b5 v+ ~
7 N: w9 x1 X0 m- \4 u

6 ^0 W/ A7 ?# I+ j【 NO.3 转角路径的乘积中最多能有几个尾随零】
2 N) z. S' j6 h( y+ |; H1 p1 C/ t8 a' Y
解题思路: {( G3 @+ b: A, N% D  q0 B: }
尾随 0 的个数其实就是 MIN(因数 2 的个数, 因数 5 的个数)
0 @8 ^. P. `4 ]
# m1 E, o% ]) H% W/ m代码虽然很长,但大部分是重复的逻辑,详见注释。# G  m  a3 U' Z1 I' h

6 n& m9 G2 f1 `$ _% }代码展示' |, `4 z+ G7 `6 V
& r- s! R/ Z* e8 z2 F
class Solution {
& j# ~6 P) X; }   public int maxTrailingZeros(int[][] grid) {
- _+ B  _1 T3 e; e1 a  [. g       // up2 表示 grid[i][j] 开始连续往上走最多能累计到因数 2 的个数
2 |& i! h3 c  _$ F* P       // up5 表示 grid[i][j] 开始连续往上走最多能累计到因数 5 的个数
# G1 q3 H* a+ D2 ]' \$ O       int[][] up2 = new int[grid.length][grid[0].length];
2 n: z: x- c8 [* I( r       int[][] up5 = new int[grid.length][grid[0].length];
$ q  ^) o) x% q" Y' m6 P' L       for (int i = 0; i < grid.length; i++) {9 |! I5 ?- ~8 `) h- R
           for (int j = 0; j < grid[0].length; j++) {
1 o) N  ]* l" T3 P  q  c               up2[i][j] = num(grid[i][j], 2);
; \' x  |3 m  U& m' P6 N               up5[i][j] = num(grid[i][j], 5);
7 s- x2 ~" B5 \: _               if (i > 0) {
4 |' Y6 z. T) \1 E9 I/ y  q                   up2[i][j] += up2[i - 1][j];3 S- m7 v* w6 f: O2 q
                   up5[i][j] += up5[i - 1][j];
  m: L4 e8 H8 d              }
! Y0 B$ v) ^2 A% q) d# Q          }+ i4 s! ]( w+ z- P4 ~* a% Y- j
      }
. i- `5 T6 Y1 J2 p, q0 |. D: ?/ Q9 k       // left2 表示 grid[i][j] 开始连续往左走最多能累计到因数 2 的个数
1 S4 @+ {! X! A       // left5 表示 grid[i][j] 开始连续往左走最多能累计到因数 5 的个数
5 V* D! A3 s( v9 f# N3 F       int[][] left2 = new int[grid.length][grid[0].length];
: R2 w) t3 ]  S9 }! c       int[][] left5 = new int[grid.length][grid[0].length];
) |, Y8 \' h" v2 J       for (int i = 0; i < grid.length; i++) {
- t, c0 J% |  f" _% {           for (int j = 0; j < grid[0].length; j++) {
$ N1 L0 r; A/ m' Q, l! i               left2[i][j] = num(grid[i][j], 2);
3 d% [) H9 ^2 ]  N, P8 m& A* d               left5[i][j] = num(grid[i][j], 5);
* n3 E4 _. X5 i# e6 _: i/ C               if (j > 0) {! w# R# N) i! a0 \
                   left2[i][j] += left2[i][j - 1];
' D6 K# Z( l4 |' |" i; d/ D                   left5[i][j] += left5[i][j - 1];
, Y$ O# d2 [% G& p              }0 P7 k7 _& p! E1 J: m: z6 p
          }
8 F5 b5 H" G! R5 A: _" K      }
% [+ [* G. `! Q( ~2 n& M4 k       // down2 表示 grid[i][j] 开始连续往下走最多能累计到因数 2 的个数
+ T" Z+ |; i) N% U       // down5 表示 grid[i][j] 开始连续往下走最多能累计到因数 5 的个数
6 p& Y  k: ^& G* B, F, U       int[][] down2 = new int[grid.length][grid[0].length];
7 P1 ~1 e& b( q, S       int[][] down5 = new int[grid.length][grid[0].length];5 d' [* O; y+ A, c! b" d* w
       for (int i = grid.length - 1; i >= 0; i--) {
4 D0 ?: w6 z1 a* e# m           for (int j = grid[0].length - 1; j >= 0; j--) {
6 k# B5 Z- g& ?; C               down2[i][j] = num(grid[i][j], 2);+ ^: M* X: t8 n5 y
               down5[i][j] = num(grid[i][j], 5);
  O8 E! |2 w3 ^/ h7 N               if (i < grid.length - 1) {
# o, ?& U1 Z( {5 t( q# F                   down2[i][j] += down2[i + 1][j];* }" _# W+ q, Q. q
                   down5[i][j] += down5[i + 1][j];
$ Q5 z) P% W7 n) V$ |              }
; `7 B& G, U& v  ~6 Z          }
3 ]! a' C+ i9 [) q$ ^- B. n) Y      }
' }$ p4 |! Q9 V0 `3 b5 E3 U  C       // right2 表示 grid[i][j] 开始连续往右走最多能累计到因数 2 的个数
7 v( Y; I! ^+ L  E       // right5 表示 grid[i][j] 开始连续往右走最多能累计到因数 5 的个数
4 G! u: t! y$ s) F3 r8 n: D       int[][] right2 = new int[grid.length][grid[0].length];
' o  v. J6 g$ f       int[][] right5 = new int[grid.length][grid[0].length];7 ^) H- P% I: A- j7 j$ \
       for (int i = grid.length - 1; i >= 0; i--) {
9 H6 @0 P: c5 h  {! ]* s           for (int j = grid[0].length - 1; j >= 0; j--) {
3 W! P3 k4 C( k9 [9 ^$ Y3 o               right2[i][j] = num(grid[i][j], 2);
% F2 Z5 I; g% @               right5[i][j] = num(grid[i][j], 5);
) P  U! d. T" w* V) T               if (j < grid[0].length - 1) {
" F7 L0 @" ?, R9 T4 {/ i3 i                   right2[i][j] += right2[i][j + 1];  Y, r( Z/ C4 }
                   right5[i][j] += right5[i][j + 1];3 {: R* @3 n' L
              }
, O0 B( K  R/ E2 @( e5 n5 p5 C' k          }9 @2 x9 u# Y! T, v6 G- }
      }) n0 N$ L' {+ O, g: N- K! R, ~" _' w

1 s9 A- d7 Q  |7 r       int res = 0;( Q( u! T5 b5 P
       for (int i = 0; i < grid.length; i++) {" d+ C7 C8 b% y/ }4 t/ Y5 J1 Y
           for (int j = 0; j < grid[0].length; j++) {
# C' p5 r) t# E6 ^& R7 k* s               // 有四种转角形态0 m! a* P: E0 n1 K
               // 1. up + left
" L! P7 A( W5 d$ B               if (i > 0) {' i8 M5 }7 b/ F% C; R" s
                   res = Math.max(res, Math.min(up2[i - 1][j] + left2[i][j], up5[i - 1][j] + left5[i][j]));
! I* c# c: w/ m              }+ u9 L8 K3 ]5 E$ }' J6 ?% [
               // 2. up + right" Q7 Y- r* M3 \9 ^; `  G- F
               if (i > 0) {# Q' Y) g: I+ _' D1 F$ E2 D3 V6 ]
                   res = Math.max(res, Math.min(up2[i - 1][j] + right2[i][j], up5[i - 1][j] + right5[i][j]));$ P) m; u* q) M' f
              }% Z, ?& b9 R" z$ @( m  p) D
               // 3. down + left
5 |8 a# }# c; Y7 `" A% y$ q) {8 i( t               if (i < grid.length - 1) {
/ y4 Q5 }' U- {  U& i/ D                   res = Math.max(res, Math.min(down2[i + 1][j] + left2[i][j], down5[i + 1][j] + left5[i][j]));
6 y6 E3 p2 L9 p$ P& ~6 n9 [3 b              }
8 Y3 \2 L, ~9 d8 ^               // 4. down + right
& V; ]! z5 I+ U) _4 c               if (i < grid.length - 1) {
1 z/ H. [2 ^9 \+ ~- [1 U) W                   res = Math.max(res, Math.min(down2[i + 1][j] + right2[i][j], down5[i + 1][j] + right5[i][j]));
6 }% _6 P6 O" D              }
7 N. O8 f) B8 ?% X               // 不转角
3 c* ^' @( X* ]7 B2 r& s               // 5. up/down/left/right
$ G& Q+ ?$ r* X9 w               res = Math.max(res, Math.min(up2[i][j], up5[i][j]));
5 i$ h5 U4 C; G& M! K8 v+ o. _               res = Math.max(res, Math.min(down2[i][j], down5[i][j]));/ J- u; z+ @: k7 @5 M
               res = Math.max(res, Math.min(left2[i][j], left5[i][j]));
, p* G' g3 t1 Y( ]               res = Math.max(res, Math.min(right2[i][j], right5[i][j]));
7 E" B4 M. k6 Q6 F* y" _, U& o          }
' V! X& @. i# Q- ^5 y. [. [      }1 W* V2 S4 g- v' \. W
       return res;7 i: ?' K5 z; v2 G9 o0 J5 f% a
  }) W  R$ k3 j3 S

3 J1 R# C1 [  A3 ?   private int num(int x, int y) {2 S" j' v* @1 J4 o/ W
       int res = 0;* Q8 D* j4 J- _8 S" z! |
       while (x % y == 0) {
4 {8 ?4 O3 q# w- B3 D! j! |0 w           res++;
7 h1 c! Q+ r/ `# ?- A8 I( U5 c           x /= y;" L! o( g6 Z- u- ~' \+ R
      }; a4 }0 F) s4 }, ]; f
       return res;, s. Z& Y1 m/ e  B# q
  }
) Y4 z/ ]* Z: ?0 y}
2 j# [" j) [( r
( O$ O0 a# v4 O8 W, C1 O/ d8 @【 NO.4 相邻字符不同的最长路径】
7 i/ K. f# f* N& D! ^3 t& d
1 N' O# c! q/ D0 s) {) {解题思路2 s. {$ k6 {9 V- c6 l
求出每个节点向下走能得到的最长路径,在每个节点的所有子节点中,挑出最长的和次长的连接,可以得到经过当前节点的最长路径。3 \5 z3 Q0 L8 I* c) R5 H* H

: i5 \4 t" K& c+ I& A0 Z& H代码展示* m# j; J7 z! u2 {+ F: f

( V9 ?3 T& \* J! \5 `0 h9 uclass Solution {6 y. l3 A& l" {$ d  c
   int res;) B& `8 w8 ?$ y( ^- k% \

" j! z4 V. b! x3 i+ P6 s  G1 f1 y   public int longestPath(int[] parent, String s) {
* z/ A' w1 S  k- N5 J5 }. E5 `, d  x       Map<Integer, List<Integer>> children = new HashMap<>();
+ K4 r9 @& F# [       for (int i = 0; i < parent.length; i++) {
  V5 p- M' l8 e/ ?# ]8 W           if (parent[i] != -1) {
& ?; S* K, U" L2 H0 m, L, [               if (!children.containsKey(parent[i])) {- g5 s5 h: Z& b
                   children.put(parent[i], new ArrayList<>());/ J1 l; ?, W% K/ _5 l% N
              }
" |/ M) k% y( ^! `3 ~$ q% i               children.get(parent[i]).add(i);% P3 W! e3 Q! `) Y) {
          }
! b& D. s6 l0 h% g  E      }
) ^9 N  H* s  s7 B1 f
$ W# [$ D# _. k0 ?% I$ X. @- m# Y       int[] maxLength = new int[parent.length];
) [6 D. }! t- z. s/ Y# a0 }: O       res = 1;
% l: {; X, Q; k" d0 q) v       dfs(0, children, maxLength, s);( b  K" W) Y9 U
       return res;
! }. R! ?$ e8 {  r" t& A  }, m- |+ P4 g1 r- \9 H7 |5 s

" e; z+ }3 h2 i+ Y5 u5 d   private void dfs(int cur, Map<Integer, List<Integer>> children, int[] maxLength, String s) {% {9 _0 m( V2 c& C, f' N
       maxLength[cur] = 1;5 ?3 E3 r! C  q1 y0 N
       if (!children.containsKey(cur)) {* P) U1 W1 G" a  u6 k! h$ Z
           return;
( z+ w( ~6 P* Y# a& R! q' o      }9 m% T2 {  W' z( A. L
       var curChildren = children.get(cur);
9 N) B5 x- G1 ]       int first = 0, second = 0;1 j; w, s3 w5 l- G& I. }- N
       for (int child : curChildren) {
6 E- U1 L: J6 D1 `           dfs(child, children, maxLength, s);2 w# j2 o9 F* J4 Z9 U8 b
           if (s.charAt(child) != s.charAt(cur)) {
8 I# r2 S+ i/ v6 v6 e1 q               maxLength[cur] = Math.max(maxLength[cur], maxLength[child] + 1);$ e, L4 f, P$ m6 E
               if (maxLength[child] >= first) {
1 b' @* s  `9 S* X: u6 `                   second = first;
0 n7 I" z; r7 o' }                   first = maxLength[child];
) B9 l1 O+ i! F2 X* ?              } else if (maxLength[child] > second) {" v4 y( W5 [' ^2 x+ _6 p: m* c& d
                   second = maxLength[child];
* ]3 P3 q' l. r7 M& N9 h& |              }9 s+ f2 l; r3 s$ T/ I/ H( }7 S* ]8 U
          }7 g; Z- l6 `0 ^: i, O8 g
      }9 M. D( K! @0 ^, X! y9 F
       res = Math.max(res, maxLength[cur]);
: H; B' \% T; Q& }       res = Math.max(res, first + second + 1);
0 ~3 K; ~& Z: J+ ?  }
% q; N. \! s$ O1 c}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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