登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】
. T% Q8 v6 [, }5 M& L/ \1 c
8 r* v+ {; J+ \/ w6 a& K4 V S2 G0 p解题思路* l7 b8 ^3 Q6 {% l6 D5 E
签到题,模拟操作即可。6 r9 O% ^) v. ^# e
# z; A f9 l" }9 U$ h2 j
代码展示
& o2 S0 [) A, B) ^
6 W( S- q3 b0 l `6 ^" q" rclass Solution {
' Q/ g. A% Q( Q' T$ I7 |- J public int countOperations(int num1, int num2) {
9 W3 F/ f% H& p' G int res = 0;4 u* k% |8 v( A
for (; num1 * num2 != 0; res++) {
5 q. @! Z3 D( r if (num1 > num2) {; a4 X6 ~; n5 I; N, a
num1 -= num2;& K" W- \; J' R* b# o
} else {
/ n- G/ n) H* N M! ^ num2 -= num1;* {& D9 E3 ?; ]7 A% E% |
}
* b7 {: W3 D' g4 {3 p, b! E }$ ?" a- |0 A8 h( a& @2 ]
return res;8 O$ T; O# d' r2 ^" g
}6 l! J3 u7 {; Q8 X) f4 M+ R+ I, Y& l
}! V9 q; ]: D; L# v3 ^
( X3 [0 d5 Y* r$ z( a' A
+ Q$ l) J3 T" n
【 NO.2 使数组变成交替数组的最少操作数】" b+ H& x g9 y. N5 W2 F# s
8 x" ~) r6 y' g$ M2 X% ]+ B; x解题思路5 x- G" P/ a! X" d/ H; O' C
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
# ^' O- ]5 V" x. r* p* k9 }: `7 h
) j8 f$ s8 _! O: a1 q8 R2 i代码展示( T/ j5 Y2 }7 L; `( V* K* H" D
" r1 k! \2 Z7 U7 c/ pclass Solution {
4 P: g( G( |* T% V public int minimumOperations(int[] nums) {; K# P" g0 |1 D, E' W+ N3 I
Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数8 {3 p9 V; z$ L3 t0 L1 l% `4 o
Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数, T: ~9 c3 e% b# Q. L/ o" V5 K5 L
for (int i = 0; i < nums.length; i++) {$ C% [0 u S/ M' ]! ?
if (i % 2 == 0) {$ E% B' c, ]0 |; D l }. W3 d
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);; ?: ^4 t: \/ c8 B; t, E$ A. X
} else {. N# ? [* u, s; r2 v( c* c
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);' S( _; h7 v. @ p0 h
}
( r8 P8 D: l: D }5 z/ U6 U6 S, Y; T
int[] cnt0Max = getMax(cnt0);6 `; w9 G6 u X
int[] cnt1Max = getMax(cnt1);
" ^2 G' R% P6 d! F if (cnt0Max[0] != cnt1Max[0]) {
c( M' v& B$ E; w1 m return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);
9 a: R8 y/ `& D# e! |, L }
0 l' d# p z; X return nums.length - Math.max(5 B' g: C7 k" i- [2 o
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
3 {) W* c5 o- [2 L# U* Z cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)( |; m2 O# G: X
);
* b, s0 a# s' _$ @/ @9 O3 \ }
6 ]: V h3 n& p/ }) ]/ M, j! e7 W' T3 K
private int[] getMax(Map<Integer, Integer> cnt) {
" z1 u7 ?; L+ k+ B% _ int[] res = new int[2];
7 ?1 y5 X0 K; x' t/ U for (var c : cnt.keySet()) {" ^& N5 l; o* C* p2 l/ E- Z
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {
2 @( [2 ^3 j T6 A6 b% y; ? res[1] = res[0];& T) Z7 t3 `! ?" A! g6 w' u
res[0] = c;) n; N @4 }9 k! \& p1 [( ?
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {) t" Q% j; g8 W7 ?1 K( q9 j
res[1] = c;
& C! _3 W+ m: ~! L6 R: x, h2 | }6 R5 q$ W; Y( N$ A
}6 v& l) F( u" k) c; f' v
return res;
* x- p# j. u. _- P: e2 @" S* R }( D: u2 O+ [ r3 b g" W6 H& m3 F
}
' k) i( h& ^! s0 N
" u& I& ~- Y, E+ n" _& f) W5 I5 L5 X: T
【 NO.3 拿出最少数目的魔法豆】
7 o. _9 ~ V" r2 r: q* \) \
. L" R/ Q* W# M" q解题思路
6 j' q1 \& }; w9 f7 x前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
+ U- l+ n0 Z! c3 e) w
* @1 K. Y' M$ B' B0 _+ p, _代码展示2 X8 ^: {) J. ~% B; c4 k9 G6 \ s
; n/ D# b2 a6 f1 J) m, D$ z, Yclass Solution {
* T! s6 N3 B, f m8 m public long minimumRemoval(int[] beans) {
( w6 D* C( V7 s7 m+ r. w Arrays.sort(beans);
R+ e7 m, @# B( P2 H# } var sum = new IntervalSum(beans);
4 l" R$ Y9 } S' U( u9 H5 `% I long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;
" j6 c8 d$ C3 E) K/ B& o for (int i = 0; i < beans.length - 1; i++) {5 O: a8 v9 j* ^& I
// [0, i] -> 0; [i+1, length) -> beans[i + 1]
O# C- @; M* I' c8 g res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));
/ j' |, F4 k' { d }& l. l, O( o6 I
return res;! P# P7 c) t) J2 W
}3 q) c) `/ v& R* Z/ c. r, J
}
# f: z$ r D7 H4 t5 s& r& ?, W- e% L7 k0 g- T, w
class IntervalSum {/ V' M7 r3 f& g$ |/ X B( b
private final long[] pre;/ L* I6 g% d$ z+ l! H5 _4 X1 x$ O- N
9 ?9 u3 [( d1 W9 {; w5 w7 U) v! f
public IntervalSum(int[] arr) {
1 \6 @- W: j$ @8 l6 e/ ? pre = new long[arr.length];
' J0 C$ ~) k- ] pre[0] = arr[0];
/ o; ?. {; P& C8 T" q for (int i = 1; i < arr.length; i++) {+ a4 ~! G, p" B( N
pre[i] = pre[i - 1] + arr[i];
- X2 m, g9 Y# o" O }
0 P6 n/ f5 [: A! D1 o$ Y# r }( c" j) i. l$ R$ G9 {
# w: d9 E8 ^$ y# \9 b& k" E // interval [0, i]
8 N9 T; g( S; J public long prefix(int i) {! W) e+ k* M- b! q" H N/ d
return interval(0, i + 1);0 E8 J5 j: d' _
}
; E. r& ` Q, h; y3 A' h q% X2 T% x/ X( r% m1 w$ }
// == interval [i, length): C! s# X" E, T9 g; u$ k1 b9 m
public long suffix(int i) {4 N" a* L2 f! ^. r- g: ^$ e1 D
return interval(i, pre.length);, a0 Y- K) X% i' ~
}
( p) ~0 ^; m7 Q3 I+ T& B; N
8 j9 }& U4 w" g& | // [start, end)' e3 B* ~0 D, n- e- L" y& j
public long interval(int start, int end) {0 n5 n; g! e8 N7 a
end--;
4 q: _. w6 _1 e$ h+ T+ d$ a6 r5 K return pre[end] - (start == 0 ? 0 : pre[start - 1]);
" s+ W% V: |* s8 V" e4 ` }# n c( S- j2 m; L. K
}
+ }+ E3 x3 a' g5 W" Y2 u9 X) R2 M5 P( I. p! z! g3 W! m! L6 U, _
3 Y' i4 }+ c l9 G) N0 n$ l
【 NO.4 数组的最大与和】# v4 D( p& Z) d5 c9 b( N
9 a5 k3 s- J5 Q! U# u
解题思路
8 A3 l9 }6 q' ] j# z记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和
Y& m# X: K7 C4 [. X: K
! y% o2 c1 T# I B9 E状态转移:枚举当前数字放到哪个 slot 里面! E4 k2 a+ l" m$ W
3 m$ F3 f q9 a( T0 A
答案:f[0]6 D, i) b' i" k" _4 b
$ j: t* f6 u& |- Q' ]
其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
4 E7 |% l8 e' p: D* v$ x$ z( h1 ~5 n- O. R& d' R6 S
代码展示
6 v: Y( h0 K) ~# w5 @' i" L
2 n5 {4 l" @+ H1 O) X1 G- Yclass Solution {
* u7 f" ~, k, y$ {: {% I% q, c public int maximumANDSum(int[] nums, int numSlots) {
. m, L1 m5 b9 n9 _( H; v: h8 A A3 o# t" T7 _
Map<Integer, Integer> mem = new HashMap<>();
, Z$ \% q2 L; O4 Q" k5 X, ]2 P return maximumANDSum(0, nums, numSlots, nums.length, mem);& a$ v. c% Q% U+ x* u& e
}
7 ?7 u1 n1 m, y1 }; v, _* F( |0 ^+ L M6 q& e G% q1 }
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
2 ~2 u- x. H9 v' C* U8 d% ]* L if (mem.containsKey(stat)) {0 q. i- t- s, |* T5 }3 H
return mem.get(stat);7 G' [+ [# X! P, j
}
/ C9 k# a* s* m4 p; |/ _ if (numLeft == 0) {
6 M0 x3 o- Z: w2 m0 o. p return 0;
& E8 r3 A9 T! j6 j" ] }
! g/ e: A7 n8 c; k" @, B0 e* ?& e; ~9 ~' n: F1 c
int curRes = 0;
" B7 v+ c8 w& R6 l for (int i = 1; i <= numSlots; i++) {
& I6 `1 V1 d' Y$ }- v9 L int slot = getSlot(stat, i);$ z6 G6 R% U5 K" T4 O% u
if (slot == 2) {/ j' v2 V1 Z' H" N" W) D6 [
continue;
% ~/ V/ }% l& T! v' j- H# @ }
8 Z" I4 k- J- i1 w& Z int and = i & nums[numLeft - 1];: f# j5 U* w, s( ^+ M3 ?
int stat2 = setSlot(stat, i, slot + 1);- B- X+ w2 a8 m1 Y
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
) x& h$ \. C$ Z$ P* L( O0 t }
; H' V1 ~; d: U8 l E0 `
{5 G! z8 p( W0 U+ l; k) T mem.put(stat, curRes);
7 i0 n# G2 G* @" d/ x! `" _ return curRes;8 X) b$ J0 t: F v, ^
}
. m! W1 S% Y2 }9 C! `: l7 N) E% C6 O' r, P, m0 l# d. e. C" H) e
// i start from 1
- X2 u8 s6 N' I private int getSlot(int bits, int i) {4 o' w/ _& A3 G% h
int offset = (i - 1) * 2;5 I {/ c& i$ m" n2 E
return (bits >> offset) & 0b11;) ]- w7 ]7 N2 A; V3 ~. r/ X
}
9 y# ~. f7 }0 |: O' C. L! D4 ?5 n; M& G* n7 K
// num = 0 or 1 or 2
' _' q1 [# ~1 h9 E0 f/ h( |# k private int setSlot(int bits, int i, int num) {
. X4 N& n6 D0 I. H) o int offset = (i - 1) * 2;7 m7 k/ d* p* f! R
bits -= bits & (0b11 << offset);
3 z) N; G* ?7 ]7 O( y( O: V bits += num << offset;
7 a! d& _% z6 N. ? return bits;
; x# D1 @* g; W" s- G0 B }
8 N" k, N0 C3 t) N; D} |