登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】! o# n! T5 V0 i4 H* t
+ u8 j R; b. k' ?
解题思路
, p1 d7 e/ U0 M" g2 q* n: I' `2 H签到题,模拟操作即可。7 y& {* [3 D Y G
% Q/ p' `1 k6 X# a
代码展示
2 D6 u1 ]6 q/ I u( C: f- ~
3 ~1 `6 l' b0 `7 n. Pclass Solution {5 z; F, K* Q/ ~& ~/ D7 `$ y$ k( E
public int countOperations(int num1, int num2) {
' p' e2 B& P- V. [$ V3 L% { int res = 0;$ Q9 }# D$ r$ Y6 A
for (; num1 * num2 != 0; res++) {- W& l7 J5 K6 W6 N6 y6 A1 d+ ?
if (num1 > num2) {/ l- ?5 T0 Z" O& |
num1 -= num2;
9 m* M8 Y% f+ T( }" V } else {5 |, l& a& w3 v" q6 M2 C7 {
num2 -= num1;
0 p, I+ W" [. ]9 ^4 H- c9 ~ }3 N- k' t8 z. a: l) k
}
& K z8 x4 D3 _) H6 z* m return res;- b6 D2 c) D" o
}
, b4 Z& K! [; i! |# h2 h9 @}
+ M& k$ `3 q0 W1 A1 R7 l' {1 B9 ~0 O, E+ O: }: o6 \2 `
! f+ ^( V5 H* F3 A【 NO.2 使数组变成交替数组的最少操作数】& N$ \ {$ n3 a) g8 h
+ E$ }# |$ E/ o' U% y
解题思路0 U3 o* p: ?" x" N: C7 B5 k
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
) K) s' G3 Q7 g$ o& i+ _, d. z$ |9 m6 @/ n3 t- q8 D* C/ p& F
代码展示
7 r/ J' O' f2 T$ i6 C- e
# o* F- l# m; Q" I4 T) [class Solution {2 B3 X) R1 K0 G0 N* Y" h1 Y
public int minimumOperations(int[] nums) {: V3 ?3 l- N* k, I9 R
Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
u5 ^7 c! G- |+ T0 s Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数
. x8 c4 c' t- w) h w for (int i = 0; i < nums.length; i++) {
: A; Z% ~# U, I+ X if (i % 2 == 0) {3 a* S; _" C& L) L1 d
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);0 A% A( N4 W& K/ E# Z: I: B
} else {
! w% N+ O1 P& f/ I- [ cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);
) O6 e4 H: t, N }
3 v& a' ?/ \- U7 G; F/ ~7 c }
2 V5 T& k. E+ e! ?# q1 x int[] cnt0Max = getMax(cnt0);6 b" `. o& m: e7 C s( W
int[] cnt1Max = getMax(cnt1);
( Q. y3 t4 ^$ g4 r& y, G; s if (cnt0Max[0] != cnt1Max[0]) {5 z1 ^% u. i! Y# K" j
return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);4 A1 V( L) ~: _: c( i
}
: h/ W# p/ O, Q& P c7 r! d2 Y return nums.length - Math.max(
4 f& O F$ w8 T+ A a, i. }$ \8 o6 a cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
3 V. \, t; }! `( }. Y: @ | cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)$ v3 M4 G% F8 o$ u7 k) ?* L( l
);
( a# z2 p- p: T, e2 S }
0 |, w+ T( O# Z: v# \! G) d$ L' g# ?' c
private int[] getMax(Map<Integer, Integer> cnt) {. k' J5 q) m$ o! G2 N/ F
int[] res = new int[2];
9 c8 R: v" O0 s2 r# { for (var c : cnt.keySet()) {
, V E5 Z; ?# c if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {" D! R( e6 R4 ]. }. P
res[1] = res[0];4 B& K! | Y5 a7 ?$ b' D* k
res[0] = c;
) g3 G7 r* H) e, [$ K' L5 V } else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {
/ s: P0 o, U3 J" s8 u4 ]4 U' e k6 L res[1] = c;
( [3 l h% ^& k! v }* @ }% Q+ B+ t g Y2 y! r% r
}/ z8 g4 u$ ?! `- [- b! `
return res;3 o) h: c$ S, U! e/ d# v* i$ M
}# P8 Z3 f, x9 \1 U% x" F' M3 U
}
0 p3 \1 A2 u9 ]. |5 ]% W* K; e
9 ?- B/ E3 O9 m$ X) A2 D( O [3 c; l. p9 g& n9 B
【 NO.3 拿出最少数目的魔法豆】
, j' P3 c2 _' ~1 {# J7 J! ~4 z: }: T( L
解题思路
" E( {+ ~8 ?7 O9 m2 X3 V前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。) F# u# f# X" c4 N! F0 B0 H
2 A0 s4 K& V( d8 N9 P/ f H; Z代码展示8 p- F( k" G" C* F, N/ E
- {+ M; S& B* M1 a: d2 Fclass Solution {
3 m/ K/ [- p7 S7 \9 \- e public long minimumRemoval(int[] beans) {/ L, M) x; p1 L/ x. E3 q
Arrays.sort(beans);
- l& J9 T, m5 V2 v, x; `- [ var sum = new IntervalSum(beans);) E3 I/ K" {8 c
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;/ U: o2 X- U. ?2 t7 f6 \
for (int i = 0; i < beans.length - 1; i++) {
! n7 L2 x- z& j9 | // [0, i] -> 0; [i+1, length) -> beans[i + 1]
5 { I8 q6 Y, W" t* _% U. ? res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));
0 M3 d, `7 h, ^0 X }
, U' I) J7 M# m& |& R+ y" n return res;7 w+ ]0 ^) K3 S6 Z: S
}( _6 j' M4 \" A$ L1 |0 G3 A% `
}# ]! A. [% b u" H/ u; f
$ R/ b6 T, M0 m7 O
class IntervalSum {# h5 Z( S- X- }3 s6 }9 |2 e- j
private final long[] pre;7 A- k! a1 d3 X1 v$ C
, `, z+ j: R" t% H& z
public IntervalSum(int[] arr) {
5 V3 E6 l5 g; l pre = new long[arr.length];$ {4 ]& b1 U" _' g) q7 j
pre[0] = arr[0];' V+ d2 E' {0 p# o* E3 H3 Z( f/ V! R
for (int i = 1; i < arr.length; i++) {5 B% @( \: d' J1 W) b0 a; p
pre[i] = pre[i - 1] + arr[i];2 h0 n. i2 S; N, e( B3 G
}
) Y( ~2 q3 H V }' x9 [) @) c- e0 T5 x$ {( W
# a+ i4 X, K( H
// interval [0, i], l |5 x+ o" z+ Q) X
public long prefix(int i) {
; r/ d6 N! I0 K, \* K return interval(0, i + 1);
; c4 |; V9 P G0 ? r; s4 F }0 V0 ~! \- V2 `" A9 q& W/ p
a4 n9 r! p4 k5 u1 Q$ W
// == interval [i, length)3 E( W/ `6 t) n0 x9 A# g$ Q( X
public long suffix(int i) {/ n; u0 s$ q) D& P- A9 T
return interval(i, pre.length);
0 z6 \2 c2 E' d- D) r: R$ y }3 g; d; J7 L# k$ n
0 Q* c, Q/ ~# k* p7 H- }4 {: V" U
// [start, end)
: q9 o# t$ `; X. i3 f# U public long interval(int start, int end) {8 k# j4 |, H+ V" `
end--;$ ~* q- q& \% F o: p% A
return pre[end] - (start == 0 ? 0 : pre[start - 1]);! D" ] Z1 u! a0 \4 u) N, W
}! ~' ~7 J; P" |+ U$ N3 s" `( n' E
}9 I' Z6 T/ |+ }9 p% l7 V
+ ]7 ?! _" I& {
7 n3 U! K0 ]& A, i【 NO.4 数组的最大与和】' I5 ?4 G) k. m5 b0 m
+ r4 m* ^6 q. c1 h7 F" b, j8 q/ R解题思路
9 _. @( x' ~8 u- | O8 g记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和/ [$ D$ I2 g |. u: P+ U- r. b& m5 \
L2 q) U, p* a1 T+ C+ d' w, K& V. W状态转移:枚举当前数字放到哪个 slot 里面2 S! `0 s2 G" x) j+ Q
. Q* O! B) S+ B7 A+ E: X- s" p5 U
答案:f[0]
4 U7 G3 [2 ?7 {- a' `3 r/ Z5 e' n( }, v4 O$ ~- _
其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
* _0 Y2 f& @4 y+ H1 t+ h6 ?; L$ p7 ]& u' B$ x- T* o- g
代码展示
' m D5 ^7 u3 u' d# v, M
9 _; h+ u, S/ i! p. aclass Solution {: U6 H. a" p+ y$ W' ?& R2 N8 g
public int maximumANDSum(int[] nums, int numSlots) {1 u7 d) [0 u" `) g0 K
* R! y; r5 t n6 V7 b
Map<Integer, Integer> mem = new HashMap<>();
$ |0 e' o% h3 ] return maximumANDSum(0, nums, numSlots, nums.length, mem);2 z3 A6 @! G( y/ w0 v6 D0 `
}, U a! O: l, z" e" f; Q+ R
; V0 S- F' {: v2 O( [ U0 X
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {6 f7 A5 k8 w) ~+ T5 m
if (mem.containsKey(stat)) {. v4 z! m4 g, j- e
return mem.get(stat);
, p" o1 V' v( w2 n' S } N) J( W+ }! E1 ^& a7 J
if (numLeft == 0) {3 {9 Q1 y, z; E
return 0;, G- Z( @% N: o! Y9 y
}
8 [. N/ {) _- N% k! a) O/ H9 o# O1 y+ `3 e- @3 H
int curRes = 0;/ k( Y- |8 k6 p- p
for (int i = 1; i <= numSlots; i++) {7 v4 N) B0 x$ O7 {; b
int slot = getSlot(stat, i);) u2 j; ^6 F* D5 L( E0 ~. j' V- G& w
if (slot == 2) {
9 b5 f% ^$ a( j7 e* N5 w# d1 N continue;, i4 A1 d9 J- ?; y' P
}) [2 W& G+ F8 I1 s' w6 U: J
int and = i & nums[numLeft - 1];
5 |8 B# A0 ?6 |8 m+ G int stat2 = setSlot(stat, i, slot + 1);
/ b: L* [2 N! R3 K+ J/ g7 x# Y curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));2 E5 g; c# J. s8 Q9 S# u
}
! d4 c' Z$ W9 |! h' {
/ [3 Q j9 l: L' f9 ? mem.put(stat, curRes);4 d! |& H# F O3 c7 p
return curRes;
- p4 t( `$ {. P( c i }
: O) R3 n3 T8 l5 q$ g" a9 d. X( v4 A
// i start from 1
2 A0 F4 `3 b# t" o& Z |4 }% V private int getSlot(int bits, int i) {, h3 y" n& h0 j* b: R% ?
int offset = (i - 1) * 2;. ?7 S+ L9 \% ^- K |9 e2 f
return (bits >> offset) & 0b11;5 S+ v, C$ i8 v8 w0 ^9 V
}
2 o+ _ s0 P7 s3 N" k" Z
5 V% B$ \0 Q) @, D* f$ @( ^! p // num = 0 or 1 or 2
* }; A p& x" b+ W0 k$ ^" B v private int setSlot(int bits, int i, int num) {! S( I& c9 I# E7 [
int offset = (i - 1) * 2;
: r. H; K/ V; d' A$ x& f bits -= bits & (0b11 << offset);
4 Y* t$ y6 j2 Q# v bits += num << offset;3 U8 i E0 r* R S
return bits;' B& h( I! A5 t6 }. e5 B2 l6 g
}; M8 r. x7 B* T$ {$ V, S- q
} |