登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
关注我们:杭州上岸算法网络科技有限公司/ R: ~. n6 q; m9 C* c) C
【 NO.1 可以输入的最大单词数】, n, Q W8 O( r# K0 {. q8 k& A
. X! Z: y, M- P) y: a6 B F
解题思路! U. G+ R' |9 l! S
签到题,循环遍历判断即可。1 |, E8 v4 z& h
3 q' R: O+ J5 s$ U' J6 S
代码展示- r7 K9 Q, ~+ p; b/ z `
( O- S1 B. _( L! U1 Bclass Solution {
: z1 z @( k8 C7 x& b. E public int canBeTypedWords(String text, String brokenLetters) {
7 h7 S8 y6 v! ? if (text == null || text.length() == 0) {
* G& W6 S6 _+ \/ N return 0;
, S$ N; ~5 ]4 o+ O$ B8 f* f }
, ~9 o# T' t/ ^) N# y1 I( v String[] texts = text.split(" ");
1 e% R1 `6 Q( A4 }/ \$ M) t Set<Character> set = new HashSet<>();, J( ~9 g7 `- p. @8 V: b: t
for (char c : brokenLetters.toCharArray()) {6 N) {2 o: g# m, I* z% ~) ~
set.add(c);
: g- j( O! e8 \ }
$ {9 x# |% O" R6 c7 b8 E# _ int ans = 0, flag = 0;# s [8 o- \2 k* Z% m' ^5 R. @9 Z
for (String word : texts) {
4 J/ n0 P* p. g3 a: N1 Z- h for (char c : word.toCharArray()) {2 j6 `& O4 E' B t
if (set.contains(c)) {) V+ H# r* Y: P4 a
flag = 1;
9 j; x! |* u' e, K. r" ~; w7 ~9 i break;
0 ~" }# g- N; v, y( | }
3 d& r3 s' Q0 ^6 Z }3 B/ c0 E( u( }; Y; K
if (flag == 0) {1 f2 _3 Z% N; @* c7 P0 c+ X
ans++;( M, G# w( ?) s. \9 S% ?
}
' f2 H: v+ k r+ I( M7 j6 | flag = 0; p9 n: N' v# l% n, s# E
/ K ]. D% t/ M! z1 T3 b7 v2 z
}
, |" l, a' {. t7 ^( Q% ~) v return ans;
U7 Y& i8 W9 b0 V; S5 }, R }* @! W, a# J0 l, ]4 R- L' o
}5 G U/ c4 p" I/ M
B3 E* S6 M* Y! J
【 NO.2 新增的最少台阶数】% E+ D8 }4 D- R) `3 @: ]
" |% Y) q. M% I+ K; m5 C解题思路3 H, |3 _ H7 W3 B( v' B% C
第二道签到题,两两计算差值,需要判断一下是否可以整除。
, q1 q9 L7 `* x
' x6 u7 ?9 q1 v% P8 |6 r$ P, V代码展示/ ~) x* q% Q; t3 |; u4 L+ O% i
4 P, o, u! Z2 y7 @3 B: R0 uclass Solution {* U' e" k/ S# @
public int addRungs(int[] rungs, int dist) {
% Y5 O% A; x$ q$ C% l if (rungs == null || rungs.length == 0) {
: `* p Z- A( p% q8 Q* O: W- A9 s return 0;
0 c8 m$ p) Y3 ^+ d; P1 h& t7 C% v" @ }+ o( y0 b4 ^/ N
int ans = 0;
4 c" x6 C8 k/ O int preRun = 0;
: s; ]4 @$ h6 W0 g( v- E5 o8 a1 R& h for (int rung : rungs) {
& ~4 O5 N; Y$ }0 D( C9 ~/ m; B- k int diff = rung - preRun;
* ^8 z H; j3 w // 整除的情况可梯子少一个
9 P3 z; _0 K4 R9 m% Z$ D: | if (diff % dist == 0) {
6 J; _ {3 s' I, F' K# F ans += diff / dist - 1;
) R4 E J7 X/ Y7 k/ Q, r2 g5 C, p }' i f c6 h% o; c; z; {! f
else {
" h# |: F' _! d ans += diff / dist;
) s* y3 G+ ^1 s9 g" J3 V5 k }
% m7 f9 e7 t( i+ x preRun = rung;4 [/ b6 u$ C4 u- f: B2 u
}
2 h# u& L; m" Y" C5 l return ans;6 Y3 p/ V# n+ ~. M. @
}9 y( }/ s$ i% m4 `& c2 R5 Y
} P2 ]- b2 {, I- H% e$ e
8 e9 T$ }! @4 `. L% o$ e
4 L" `, t) G/ a" E$ ?' n
【 NO.3 扣分后的最大得分】; |# C/ b6 s' X0 f
7 Z6 N7 v+ v, t; ?解题思路
- C- Z) p3 |: W0 Z4 [* P1 i坐标型动态规划
) i9 F2 h3 ]1 Y& \
) s& L$ I7 p) p2 I2 B: O! ^& |dp[i][j]表示处于坐标 i j 的位置的最大收益
' w4 b6 o5 K+ E2 d' `/ D- W; m6 I6 B ~8 l& R: N
普通的坐标转化会超时# F8 Z @% R6 e
6 m/ H& o( p% N0 H2 c考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的$ o: A7 x1 |0 r' D$ X# A
" z( v. P6 o/ O3 ?. C! b
因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用4 a6 w- \7 o7 Q" O# O
. j& r3 [1 Z. P6 P7 h) v+ z还有优化的空间,i 可以压缩成两行% k; y. w4 L+ R8 w$ v# _
: L/ L6 J( A$ E& ~
代码展示
1 }+ p2 b2 B4 a% J" M6 w1 j% |) R g$ y! J1 W
class Solution {: c" J; v. m+ _. C( \
public long maxPoints(int[][] points) {
, Q! @8 ^7 s _: F if (points == null || points.length == 0 || points[0].length == 0) {; d% d$ K) f$ p% M T! B
return 0;
' z+ x( `. t0 Z/ W }
' ^3 L# i a- ~9 p int n = points.length;
/ ^$ L5 E l, u1 w8 P- A int m = points[0].length;
, o; X3 @/ v) p4 T4 E& X; ^' D1 H+ s" F long[][] dp = new long[n][m];
! P# G- e4 Y! a$ V2 P6 S# G B; Z // 首行初始化
6 g( H; s" E: M; r for (int j = 0; j < m; j++) {5 U* S% R1 i% D" }
dp[0][j] = points[0][j];
8 w' v# @6 U4 A& | }* f; a) ^0 R' x2 I: I# e
for (int i = 1; i < n; i++) {. a: b. q3 O" _7 u0 l, ?+ J
// 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;9 }& ] w* o3 P
// 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;
& ~; P" M& z) ] long leftMax = Integer.MIN_VALUE;
; _; i; a9 G/ p, x" g) D9 I long rightMax = Integer.MIN_VALUE;
! ?+ I' O% [) F! y! e" n3 [- U for (int j = 0; j < m; j++) {4 X6 a8 Z$ _( v$ j
leftMax = Math.max(leftMax, dp[i - 1][j] + j);5 [0 V9 [% W [. C% t3 o
rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));7 O& z6 U( t9 F8 b
dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);. c1 s' [5 ~* L( D
dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);& |) v6 \) R+ g
}) y$ J+ ?9 f: B
}, H- ~# ~8 f" Z8 Y" |
long ans = 0;! `5 W2 m; E+ d5 }" W
for (int j = 0; j < m; j++) {
% O8 s2 B9 a7 E! \9 Y ans = Math.max(ans, dp[n - 1][j]);2 E& n# h! \ m+ }: R; }2 `
}( F: u0 Q) M$ F. e0 a7 I N
return ans;
' q: r; G2 U y7 Y }# A' f+ l* U# m( I
}
, Y9 ?- ^3 @% p7 \1 J( c- {; p1 K1 C" o6 a a
$ |' D: h1 d9 X7 l3 b) G【 NO.4 查询最大基因差】
2 d6 t% M. s* \( s/ x& L( K6 W' U8 Q" W( m
解题思路 T l o5 [8 l, ^1 w
二进制的字典树:将数字转化成二进制记录在字典树当中
. H. T; _/ v, e/ b+ K0 I" x1 r+ G6 H& ?) ?2 b8 m
构建树,方便做DFS
+ e' V& }, {+ D/ P2 o5 ?9 U0 a$ F3 |1 m2 ?* m# J
每搜索一个数字,将该数字更新到字典树当中
a3 H: r$ I `! i3 G$ ]& {! P/ R2 Q
在字典树上计算最终最大的异或值4 R+ `5 J S! b4 b' q: ^
4 `7 }7 d: x3 ?2 a代码展示' Z9 L' ^, f: A
6 K0 r, x) @- [1 p8 w% O6 r, r) A7 }! Q
class Trie {
1 \% r& e' s# r! O Trie left; // 13 O8 g2 `( \ a- I5 V2 D0 r
Trie right; // 0
. z( B# D2 E' b# ] int[] count = new int[2];1 m& u1 M' u0 L9 V+ u
public Trie() {}
( A+ P9 i* U- j6 Z5 K" d; Z& f; F0 c S
// s == 1 添加, s == -1 删除
4 F; m) C3 @# q* P0 I public void insert(int val, int s) {: t* o2 T r* D1 b: H! ?! D
int flag = (1 << 30);
1 v2 M; l5 x6 k0 @# ~1 [- E Trie node = this;3 B) k7 G" B' a6 `# z
while (flag > 0) {$ G5 Z1 ~: v4 i
int bit = (flag & val);- t+ v, k s. l5 Q3 O3 c
if (bit > 0) {
# K2 o [' Y) ]& {$ z$ \0 p // 1 走左边
9 |4 |5 S" f1 K* | if (node.left == null) {1 ]* @4 t6 ~2 X. s8 i8 s
node.left = new Trie();
3 T+ p& Y8 G9 f. K }9 E9 i1 X; l6 f5 h+ L# r4 ~% j) D8 u
node.count[1] += s;# U- x+ C; s, T
node = node.left;6 W+ E. U Z) b) r$ j
} else {9 p# e# @; _2 }: F4 w: b1 j- ~
// 0 走右边
% J; h9 I5 e; T/ S/ _. T if (node.right == null) {0 F" U4 T/ G1 w9 i+ ]- M
node.right = new Trie();
( e! s% { r$ \ }/ U) x( g- y3 E* T1 }' I$ q) h2 W2 }
node.count[0] += s;) S: g4 p. z! ]* h# c y- m* b( i
node = node.right;
+ J4 r. _- e! \3 l% d }
: k, y+ X Q. u, S6 Q* W3 b flag >>>= 1;
) X1 G. h( ?! F. L }
# Q. K+ i: x* l& o0 u3 f8 e2 u2 w* e) V4 W }& c- A& E. X6 s5 V' E
^2 n9 D+ V( Q! M+ k" j+ t R/ C public int getMax(int val) {
2 n6 V4 e, w E Trie node = this;
2 I+ J* n2 _# e% K! f* Z int flag = (1 << 30);9 x+ a9 Q2 m( X0 x$ l9 a; H
int res = 0;( O. n$ C! i2 Y; j7 c, t: p
while (flag > 0) { j0 i; ?$ a; q# q9 {3 V3 J
int bit = (flag & val);2 F+ X9 F7 o/ E6 P- W! y% d
// 贪心算法,1 的话走右边,0 的话走左边
3 K5 r* M, Q* h8 t, n9 k if (bit > 0) {
6 C0 M* |5 a0 W x; V$ B5 x% i# h // 走右边,右边不行走左边% K- y3 s% Y l
if (node.right != null && node.count[0] > 0 ) {
% S: G! L4 G5 M1 I4 E' {8 I node = node.right;
@4 D, ^5 G8 W" P' O# i res |= flag;
0 \% B% R1 _' F4 s! _- T6 u } else if (node.left != null && node.count[1] > 0) {; ~5 j8 \4 D8 c9 @
node = node.left;
5 c9 j4 ]- L, }+ [* F } else {7 C+ F$ a3 g" |0 ^6 U. X j# Y
return -1;
, M$ t2 Q% Q( _8 v' G# D }
* [/ u3 w- S! N( Q# [& L0 o- V } else {% C- y6 w+ Z6 M7 |3 d1 Z5 }6 s
// 优先走左边- A" U# l X/ k9 ~2 |" I0 c
if (node.left != null && node.count[1] > 0) {
) u! c+ ^0 R# d* j" \) Q. w node = node.left;( Q- J- J2 I; a* J+ I
res |= flag;- V1 h$ g6 M4 ~1 v, l
} else if (node.right != null && node.count[0] > 0) {: `3 w- w' t! w- |2 m4 p9 M
node = node.right;: ^0 X9 k- [- E% Q% g
} else {6 `8 p' W1 `) E& l( X1 I
return -1;
) ]8 }; u2 L/ l% b3 R }
6 _( @" H( Z% B" ]" m) X9 B8 e3 R }
' ^. R1 z1 W) } v5 L0 @: b flag >>>= 1;5 Y7 H, y) M; _2 |& C- W
}
! m: ~, W- b# K1 S" Y$ \2 S return res;: B9 H& X8 D \( L( O% M( n
}
$ Y7 ]5 M- Z }$ N9 t8 N}6 u4 y$ f/ G4 j2 d+ V! z
public class Solution2 {6 l8 {5 }+ O) v/ b5 Y6 ^6 ]+ W
static class TreeNode {! ]! W( U$ ~$ [7 _8 n
List<TreeNode> son = new ArrayList<>();
9 h# ~; L8 r5 ] int val;
7 Z: l' |% A. g, M2 F* `. I" G public TreeNode(int val) {
6 O* `: V3 h4 N8 S4 Y this.val = val;
9 f$ D/ @ T9 ^! T' o5 v/ | }
, p" W( B) ^4 c$ a) C) ] }
% ^: j5 g) u4 ^. H Map<Integer, List<int[]>> map = new HashMap<>();5 k2 o; f, @; u3 W, D. s
Trie trie;3 m9 b3 V! ?+ e: }
public int[] maxGeneticDifference(int[] parents, int[][] queries) {
# }1 u8 ]( Q. y8 w( Y" {' S int n = parents.length, m = queries.length;
4 N* F% B. @5 l // 封装查询的信息
" N) O$ p6 o4 n- l. r. r; j! F for (int i = 0; i < m; i++) {, K- }3 Z" W& ]
int node = queries[i][0], val = queries[i][1];
. L i4 E6 s6 c- i if (!map.containsKey(node)) {
' q: T$ @8 y, i' \6 A map.put(node, new ArrayList<>());
3 K( q) {9 ~, k }' I h8 D, y. y
map.get(node).add(new int[]{val, i});
i1 i& h" [1 F( O8 c }
9 ^6 v: D, R& H1 d Map<Integer, TreeNode> nodeMap = new HashMap<>();
5 y+ W+ ~: L9 h% P& X // 构建树
. ?" c0 X' A, ~9 a: M TreeNode root = null;
+ N v4 n$ h1 M- ~" E3 V for (int i = 0; i < parents.length; i++) {, _& D2 ~0 x! P* `3 M5 H: N( C
int p = parents[i];& V5 `& g$ n |
if (!nodeMap.containsKey(i)) {. b1 e# X; {2 l8 J- m8 F% ^7 m
nodeMap.put(i, new TreeNode(i));
4 H7 u2 @$ l" \' u( c* V7 E }- m+ m+ f# a2 L8 O1 _
if (p != -1) {( Q8 P# u: a! } L
if (!nodeMap.containsKey(p)) {
; e( T2 H" |& b8 Y* | nodeMap.put(p, new TreeNode(p));
1 }# `( R$ o% U `& l W }5 w/ N+ ^" }! ?$ {7 @1 G
nodeMap.get(p).son.add(nodeMap.get(i));
" D/ S2 d0 e# c4 x+ d8 P, | } else {! d8 s5 F* E. v4 t$ p1 s0 e+ |7 P( L
root = nodeMap.get(i);9 c. p* i# c# n( G
}
3 f* {/ z) O8 a# I2 P* B9 s" Z4 s }4 y0 Z% j" N8 T$ I
trie = new Trie();
, N* B# l) [7 R- \; n int[] res = new int[m];' I) Q. L. \7 q+ k5 i2 F9 ]
// 在树上进行DFS
7 E: {* N s" C( T- P8 q dfs(root, res, map, trie);. b5 v0 F, G5 I: e
return res;3 O; w9 e9 L+ v" Z; @$ E
C% m$ U8 t" A }% P2 O8 m5 Y9 p
; u5 B% H, s5 B" a5 n6 L( @" h
private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {
! w# z! Z- g) u2 k* J if (root == null) {
1 C& x: m; F" |" } x return;9 t2 O" K, b7 A! ^: w
}5 C- |& D% o& Y& n- C* U4 [$ O' \
t.insert(root.val, 1);
7 E1 }) W( Z% g: K/ J if (map.containsKey(root.val)) {! q5 t+ g4 Z. `! D Y) D' `
for (int[] each : map.get(root.val)) {
H0 M* i; {0 f int idx = each[1], v = each[0];# l2 A" {* |( n5 o$ f; f
res[idx] = t.getMax(v);5 i; Z9 d# X9 y( `4 B
}% z! ]% k: d+ A6 L
}; J/ w3 X0 q+ t# n! |7 b
for (TreeNode s : root.son) {
8 I5 ?* _ O S" Y, p B' \ dfs(s, res, map, t);
' w: [# q0 p/ O% H6 p# [0 Z }6 j7 O2 E7 D# l) D7 t" A. o# j
// delete
; V+ I: {& W( a# U0 g t.insert(root.val, -1);
4 m7 y; D, Q! V* x1 P" s3 o3 p }
6 c G$ r& p6 e' ?- @7 h' P5 |4 Q! A}$ h- T+ ]1 |1 w9 Q: c- Q# Z# L
( u0 a6 \/ w$ n- B- [
8 i. S* A5 c$ f0 j6 [$ U
|