登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
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
} |