登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
关注我们:杭州上岸算法网络科技有限公司
: z& e! u- q& d& Y" s3 N, c6 C【 NO.1 可以输入的最大单词数】
# U- V/ ~- g, W$ S1 K$ g9 g9 i9 A7 V% M8 J0 l
解题思路6 H* @, ^$ I; r
签到题,循环遍历判断即可。7 p) I$ i7 F G, t5 t
R1 w; h6 J$ R1 w' Q
代码展示
' |7 n3 z) K1 ]4 U4 z5 e; i; i+ q" H* U) v5 c
class Solution {
/ [) w b* f4 u) I- B/ C public int canBeTypedWords(String text, String brokenLetters) {
7 e, \' q# b; M- o( q& N if (text == null || text.length() == 0) {) b5 n" ^( Q! d: E1 V
return 0;9 Y8 Z) H5 G2 c
}
1 P. B( ~' S, s String[] texts = text.split(" ");7 T, L% m' E6 R' m9 P, m; M
Set<Character> set = new HashSet<>();) a% q0 t9 p; Z; `3 O* z" p
for (char c : brokenLetters.toCharArray()) {6 W t) o p: r8 C7 {- u7 i
set.add(c);$ u/ C X+ }: Q, C0 |- ~# S0 B
}
& V. Y$ c6 U' Z int ans = 0, flag = 0; h) v5 A; f2 m* ^# s s
for (String word : texts) {
4 W4 _0 w) x+ G( u; I7 N9 @% N' N for (char c : word.toCharArray()) {
9 g0 X3 n% g6 ~) A if (set.contains(c)) {% H6 K! C8 \. l7 J
flag = 1;
3 |$ A* h) U# \4 T break;1 u# T, `+ i1 u- S; M
}
# J7 o5 m' M! a }
7 @' {' |* Y: ~* c1 O2 H" g if (flag == 0) {
1 b' b! i% L' c/ Q0 B- K! e ans++;4 Y( M1 K! |& a; J. v
}
' a- S8 l9 a* L! Y8 Q flag = 0;' d" x0 j8 }# z! g: h8 ~
0 N/ w i! V3 z0 F& Z }4 G8 O" M7 v' {$ F4 e: D
return ans;
7 F9 \9 V5 M2 t" s# I } w0 b* C2 Z+ e8 ^
}
( _# h! o: U3 J q: f1 z8 M1 Y' n, i
【 NO.2 新增的最少台阶数】1 r3 ^. Z$ [& J* C- P
. I q: |& S' `3 N
解题思路9 s+ ]# {! p3 x3 g
第二道签到题,两两计算差值,需要判断一下是否可以整除。
+ d; Q2 F+ W c- ^, g- q0 [5 N. y' }& z3 Y8 N# L
代码展示9 ]3 r) r5 B8 f$ [% d- N: v+ h) e5 e
8 w* U+ O9 w+ m, c3 F
class Solution {
7 D; m- S# g2 Y3 Q5 \6 [) O public int addRungs(int[] rungs, int dist) { d2 _1 }2 [' T4 X! ^" w$ W
if (rungs == null || rungs.length == 0) {0 _6 j! L& D0 G$ @; B' B
return 0;: t0 {2 D/ V1 S
}1 P$ K# ]* I$ Q4 z1 d
int ans = 0;
1 z7 F- p2 C ^6 { int preRun = 0;9 W3 q/ d4 M0 [' b" j j$ X% ^% L
for (int rung : rungs) {: J8 g% t$ I w1 y
int diff = rung - preRun;
) l/ h5 Q( w2 ~0 i; S& V3 o // 整除的情况可梯子少一个
) h9 C0 u- X3 Y/ J0 u3 h; F if (diff % dist == 0) {7 n/ Z" Z5 J8 a) f, _
ans += diff / dist - 1;
& x5 u& o- E. v" {4 P1 o6 I }
8 ]1 [8 H- L1 |9 J7 [+ a else {
3 N7 _4 u! a4 z6 ^ ans += diff / dist;' ]9 M8 o% D) C4 F; K+ \1 S
}5 B8 K6 N; [' q' a
preRun = rung;
+ @+ E% y+ J6 U/ O/ Z7 [$ N }
5 X5 g1 C9 H3 F$ @7 g. l return ans;
0 a$ K0 g2 v' E8 p0 o' o }
5 B8 a6 Q3 G+ W* I}
+ J: X% O( v( g0 r% w. z4 B9 D' ^+ C, X
$ o- J- L' h9 `. E' U7 K; Y
【 NO.3 扣分后的最大得分】
N/ d* X( n5 x! G# g# F9 \6 ^; o0 a' @0 n7 O ` G+ \ P
解题思路
0 p* `3 v7 ^" ? d. s1 ^" e' M0 w坐标型动态规划. N8 c% [+ v/ q2 v* H
) d2 n9 I. ?! ~# ^9 r: T( O( }' D; g
dp[i][j]表示处于坐标 i j 的位置的最大收益
7 e |/ N o- o" ^; l/ [/ J
4 L9 E9 X C2 ^' ]/ S- `, {. w$ `普通的坐标转化会超时
, p1 R0 P% ?& Q) J U9 V% X; y3 B2 O# @
考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的# v! }( g* S. `' L5 J$ a
( [" n- K) c6 G. T, J c9 Q4 `+ c因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用
9 h$ K& z+ i$ y+ G9 y- L+ |+ s; U v- @5 i! w6 @" `+ V
还有优化的空间,i 可以压缩成两行* i2 L0 p! \5 ]: D1 ]; v
0 A, p) {) j/ s3 h
代码展示
" j! ^ {- G: E6 K. X- O) c+ `& D8 F7 v4 a! C5 f) b
class Solution {
" b; J5 M$ W3 j! K! z6 d public long maxPoints(int[][] points) {
6 ~3 }) y. N, k9 b/ s. J if (points == null || points.length == 0 || points[0].length == 0) {
. S2 Q! S9 Q- n+ H return 0; E+ o9 t$ r P; y0 t' q' ?
}% R: t9 A \' W. H4 a8 `" Q
int n = points.length;
& d6 @* U% m/ J" o8 c+ t$ F% c7 t7 d- W int m = points[0].length;
. Y: U) v+ N4 N0 I/ k9 w- f; z7 c long[][] dp = new long[n][m];
8 b8 M5 G+ @8 L6 G // 首行初始化
! H) C% x$ s4 `! a# m for (int j = 0; j < m; j++) {
: u9 X0 Q; E5 o* I9 O dp[0][j] = points[0][j];
: s8 F3 ?& \/ L" L1 E& J+ M! P& S }1 n' Q; z# I! D! J! {
for (int i = 1; i < n; i++) {
1 j; f% E e2 e // 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;
4 X! u1 T' ]# K // 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;0 l6 ]5 K7 O+ ^5 e. s+ L' b
long leftMax = Integer.MIN_VALUE;
* m e s* {0 y) A% R$ L, y long rightMax = Integer.MIN_VALUE;
, m/ e' H ^/ N# J Z for (int j = 0; j < m; j++) {
5 z: N" P5 g- ?8 V! U" u& ?8 |/ ]3 | leftMax = Math.max(leftMax, dp[i - 1][j] + j);/ `7 E# v% e+ ~; f: H- ?
rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));
$ ?0 w8 [! q+ ~2 P dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);
" d2 Q9 K3 v$ [7 U; Y" L dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);( Z: I4 J* ~, R, n. ^
}
2 I8 X! W0 k' V }
, D' \! T0 W- N' A' q% ^ long ans = 0;
8 S% D& _& ^) b- E8 l- W+ t for (int j = 0; j < m; j++) {- d4 j: ~# m& [
ans = Math.max(ans, dp[n - 1][j]);# ]& s4 {" B4 U" V/ Q
} {6 c1 U) g4 S$ ~
return ans;
9 V6 X" Y& H) @' E }2 `: X% l' i r: Y
} f: S" }! O; F; k9 j; b+ \
" S; y# L( j, u) J% n
, f0 Y- |( @' W5 I' y) X3 ~【 NO.4 查询最大基因差】
9 G8 V% X/ T# M' g3 j) U
2 N) |2 t& I1 y( s* G$ r解题思路
5 @/ o5 T* ^9 v二进制的字典树:将数字转化成二进制记录在字典树当中
( U# d* y) R$ B% ^$ ~* [) h
7 c# V; O7 D. c/ u1 D' V构建树,方便做DFS2 `6 X% `8 Z5 Y R
$ x3 E, o( S, o每搜索一个数字,将该数字更新到字典树当中% h. { L F5 O+ @
# G+ F+ F+ i& L6 o4 z/ j6 U! e4 a! b在字典树上计算最终最大的异或值
! U' p S4 J( t @
: e; K3 h: y& N" x! U$ h代码展示
2 v5 \8 I7 ]$ I C# h# D5 d0 B- o' }
5 Y$ v1 _3 s! c+ Uclass Trie {
, W* C7 U; @, Z1 k% _" a7 S Trie left; // 1
6 Y4 U K/ K; b6 E% m9 j! @ Trie right; // 0
3 l8 L) J1 v y) X2 \% }( d% x% t! y! X int[] count = new int[2];
F, @% X( M f: v, u, K7 p public Trie() {}; ?! J) H# e! M' r9 R$ W: W
' r+ ^; F! o7 I% o# O' t
// s == 1 添加, s == -1 删除& E6 v. l) K5 ~! g
public void insert(int val, int s) {) J$ V& f. X( a& ]
int flag = (1 << 30);1 N4 f, R: J1 o2 k7 d
Trie node = this; C' z. p! o& y) j
while (flag > 0) {( V5 f- {- F0 z! k
int bit = (flag & val);) C A3 Y2 `, ]" r* q2 e
if (bit > 0) {
" t, F# A7 z( U3 \9 V // 1 走左边
* o8 r" O7 n ` @+ ~( x if (node.left == null) {& Q' s {9 G0 @) f+ N6 o8 \' k! d
node.left = new Trie();; h* [- p) B6 h2 f5 `# Y" U& r1 W" x
}3 W! E2 ]; E7 q. r
node.count[1] += s;' \; G3 E5 v1 t3 y8 _- p
node = node.left;
3 Z: D _7 y# {+ J } else {
. S6 C; Y9 l+ p( l6 @; {. D+ Z( k // 0 走右边
- G; H8 D- v; T, b, e if (node.right == null) {
& }' X0 R* z0 r9 M0 j. | node.right = new Trie();
. }" F" x% f+ \+ _ }
0 P+ C- [9 A: u+ d7 j! C4 T node.count[0] += s;
! H7 U6 b: B$ S* E+ x. b node = node.right;6 R3 C" i2 f; Y! I w
}
0 O' N5 z( Z% j) z flag >>>= 1;
. }3 k- ]* U+ Y7 @- D; z! v }" n% M$ [: I7 _' N1 i" c
}& ?7 q- X" r7 p1 |0 p% O7 j
; @" c3 U7 a6 i( a% T
public int getMax(int val) {* L; h" g0 H" w
Trie node = this;
0 N1 T7 s1 Z& g$ F, h \, k int flag = (1 << 30);5 H& D: m5 V/ y% M( B2 p
int res = 0;
/ t2 L% r' m' w# [- x2 {$ W while (flag > 0) {
. `0 i; i- j$ g; M( g# p int bit = (flag & val);
9 [* e3 f- g5 [ // 贪心算法,1 的话走右边,0 的话走左边
. r' g$ ~! m* }. d if (bit > 0) {% }3 v9 n1 |( n- ^
// 走右边,右边不行走左边
. I2 _( [% }0 e0 }% j if (node.right != null && node.count[0] > 0 ) {; h; _& m4 G+ X/ |2 w! P" ~ u2 c
node = node.right;
* Z3 e! h' x& J* n# Y res |= flag;
8 a$ @( G1 a' G } else if (node.left != null && node.count[1] > 0) {/ @$ V; I |& a& k% m5 V4 g% f
node = node.left;8 m# E' c3 {/ W G' f
} else {
: d7 V( o& m2 P/ h& N" K* k return -1;
]. _9 d$ ^; h: N }) |: @7 G4 o1 m8 z+ K' H+ c- A
} else {2 A) J9 p7 }' A( a) z& u0 n
// 优先走左边
0 t) c5 T1 ]8 t2 X% H! l if (node.left != null && node.count[1] > 0) {2 w9 M/ R3 D I# n B
node = node.left;
9 r+ p, i/ Q/ l# z, J res |= flag;: \9 r: [( e/ [1 T7 M
} else if (node.right != null && node.count[0] > 0) {4 W% t% k$ M" l+ x
node = node.right;( Y; F+ F9 k0 W1 k
} else {( m7 |. C/ d! g7 x! D4 r
return -1;
' v' a" C) B% w0 w. _% M: i! s }
: V8 _3 q" n/ B9 m0 Q) c }; L, W8 w7 v5 ^6 [
flag >>>= 1;: `: n' O5 O9 m# V
}
$ s9 \- Y/ j8 i0 v return res;
2 i- [$ \3 }2 a0 g2 {% K- i' ~ P }
- n! D. c, f8 _! m( A}/ ~# T; Q/ _9 L3 }+ P
public class Solution2 {5 t3 ~1 i/ }0 |. M0 L/ F" i
static class TreeNode {! T6 ^. ]+ L9 Z9 f
List<TreeNode> son = new ArrayList<>();9 a! U! G" G( w; `
int val;; D$ b/ W2 ` M& ^5 r5 \
public TreeNode(int val) {
2 U5 I* ?1 G' i/ h this.val = val;' n7 _( P0 r8 o. K: g
}
' R2 o' D3 a$ w: h, C+ @ }/ r J- |( V# X/ Y" v, {) |- L/ |
Map<Integer, List<int[]>> map = new HashMap<>();
4 y3 A, F1 R0 K7 ]" v) A4 }7 g Trie trie;
8 z. Q) W! c1 W% a6 @ public int[] maxGeneticDifference(int[] parents, int[][] queries) {$ b: U' a9 G9 L2 P6 w
int n = parents.length, m = queries.length;
# b5 m" }) n. d8 d( o2 f // 封装查询的信息
* \7 w* a$ u) m2 f for (int i = 0; i < m; i++) {, n- U6 `! q5 F$ }
int node = queries[i][0], val = queries[i][1];
8 _% ~* e' n S1 v4 X if (!map.containsKey(node)) {$ J! v5 ?% O+ Q9 Q; h
map.put(node, new ArrayList<>());6 ]6 W Z) u9 g! H4 A* E' J. U4 s( p
}3 g, o/ }- f$ L
map.get(node).add(new int[]{val, i});
/ p* g' r' b" U }5 I" ^; ]7 y% Z' _9 h
Map<Integer, TreeNode> nodeMap = new HashMap<>();
1 ^7 y& |3 m5 T; Z3 B // 构建树* e+ k% z3 S6 D* B* }* k
TreeNode root = null;0 x7 n# z5 t h7 @
for (int i = 0; i < parents.length; i++) {: F! b. p6 f, t
int p = parents[i];
& `3 V7 ^) f- s) L if (!nodeMap.containsKey(i)) {
( i+ G. z1 I, j8 |& a8 I nodeMap.put(i, new TreeNode(i));
2 D2 _6 ]2 u9 y0 D }5 K3 e3 Y6 b5 {3 M. ]# N4 t- G
if (p != -1) {
. p- d! J; A7 x: V- t% X* a; n4 L; J if (!nodeMap.containsKey(p)) {
; W2 P( I9 ^& K; I$ b8 g, z nodeMap.put(p, new TreeNode(p));
$ Y: R' H3 e/ d }
, i8 l! {* m7 L+ k% I- d, T% ` _) @ nodeMap.get(p).son.add(nodeMap.get(i));. M; O2 M$ f" z: ]
} else {
* M9 R3 z' k) X) _ L- y root = nodeMap.get(i);* T( V; n" G9 M& Y
}, |# O/ s7 v: s+ A1 Z4 `. ?/ _
}1 \6 N* J: I! T& m
trie = new Trie();
( m; W) K& T" Y& a( s int[] res = new int[m];
( M, Z4 K D a2 s3 M* k/ y8 @/ D // 在树上进行DFS
% l% Y1 x4 Z" ? dfs(root, res, map, trie);% P1 w/ z. c3 D( I. j+ |/ ?
return res;
9 i& B9 v0 t! X1 [2 M$ X2 Y4 k: |0 I7 b3 c G0 n
}
- q! H0 K( S9 h3 U, m2 \/ m% V( [6 p1 q2 n9 C3 P! A
private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {
0 M+ b P* }8 z if (root == null) {
) q7 _( `& J5 n, N; U7 C+ u return;
5 J" ]1 a$ x) F" G5 ] }
+ i& W) C: G$ m. e: `% k1 {" ~ t.insert(root.val, 1);: d) D. R/ ^# s5 U6 S( P
if (map.containsKey(root.val)) {
! H0 }4 L8 _# G) ~" }+ {" D for (int[] each : map.get(root.val)) {9 o. z+ ]5 y4 |) w( m5 E9 T
int idx = each[1], v = each[0];$ e) y7 P; G) K, B" |6 }+ e( C
res[idx] = t.getMax(v);
) D+ z2 Y$ s5 q% T9 u% o8 S! S }# W6 M: u3 l; S% Y
}( {# Z' ~7 F7 s! U) N
for (TreeNode s : root.son) {
/ e* L q3 _) t M: m; Q/ V dfs(s, res, map, t);
, l& i3 t1 t# w }
& n( V9 _$ ^! x! s& c // delete
- u6 h4 l; ~/ U) m7 I t.insert(root.val, -1);; a: s. q8 P/ g' `7 S4 u: @
}. `* B; G5 r4 f: X/ A! {' |
}% z: Z9 S: m( B- n1 r7 z
- Y! |4 U# S0 ~/ g6 s* f
$ z T z( X) A
|