登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】2 q r+ L0 I0 q# \' d5 \# @
. a, N6 ~; w. d' u4 n解题思路
3 ]9 s7 _. J |. w( v3 H6 B签到题,模拟操作即可。- {8 w( \ V. t% h4 Z. @3 [# ~
6 I: j/ x! k' |; C6 L
代码展示! N: }/ ]1 ^) f, q" s! q" N
* b( l& X9 g! ?/ n7 n0 s
class Solution {
+ ~! e- D, K- _) _9 Z/ T public int countOperations(int num1, int num2) {4 a4 M+ s4 V- T5 }4 w: O2 i6 {
int res = 0;
, R( c6 F5 j9 i" ] Y9 K for (; num1 * num2 != 0; res++) {1 J1 w" N, A# C2 p9 m+ m
if (num1 > num2) { N1 d# Q& y% g. |0 o$ d
num1 -= num2;
8 l6 Z# E/ w- N/ Q3 v4 N5 k7 k } else {
7 n& f2 A) c( c; F2 ? num2 -= num1;) C* t6 V% B& M" f% A; I: B
}( `. Z1 \! ?! z; f
}
7 i& v) | m, l6 c( T8 m7 }- K return res;
- M9 s+ X& e4 h" v* T+ v3 ] }5 z% }) m* C, a
}: C- O; o' n$ M" Q" @; K
' u, F3 }' D/ L) m" }( c
+ g* c8 |- ~* @9 w4 @; M; M【 NO.2 使数组变成交替数组的最少操作数】' ]+ a/ V- H2 {3 x3 }
- Q u) ]9 ]5 F* r
解题思路7 |; k0 _3 a7 D, }. W$ v/ W
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
2 o: d* G! J3 y( {2 P; O( B3 S3 V! e1 t3 G3 \3 a
代码展示& v" Z: [0 u1 C- n
0 a& D" _3 s: y) \- I! y7 uclass Solution {
0 }: i4 d8 m- m" o# t" _ public int minimumOperations(int[] nums) {
( ` {) ^" E0 Y' j Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
5 C0 a* R5 o# {/ Q8 j Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数# i( k, l' Y% M2 n: c
for (int i = 0; i < nums.length; i++) {# X. r, Y% ?9 B* r/ |. v# @! I% v3 Q
if (i % 2 == 0) {
6 e+ b5 \0 m( y6 P cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);, V7 x0 [0 @* R% X6 q% a! C
} else {
+ s; j4 C. n% o$ e cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);
, U+ b1 u5 E* R }
( @" y& j" Q0 e+ L' F" j+ K }
* g2 N5 |+ ~( s" Q0 T* I4 R! j3 C int[] cnt0Max = getMax(cnt0);
. ?& a! _0 U s int[] cnt1Max = getMax(cnt1);8 r! @, u; Z9 n: K- e+ l0 Q
if (cnt0Max[0] != cnt1Max[0]) {7 |4 V7 N) x8 _2 }3 ~) G' F
return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);' `# r: G( R* }4 Z
}
1 z/ w/ B: F$ _ return nums.length - Math.max(9 p- Z6 @7 I" G- n; V
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),) X8 Z7 z; F0 X7 T
cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)0 X" a3 _( D( S X! q; y! B
);- ? B, e0 i4 }: X$ k- p9 ]0 D0 t
}
" A% Q- l3 J7 n( i6 i0 E' u8 i& P: E3 Q# Y
private int[] getMax(Map<Integer, Integer> cnt) {
( J7 o% E: ], ^5 c* A+ h' v0 [' f0 u int[] res = new int[2];( R$ s. z0 n3 t u: b- E( w
for (var c : cnt.keySet()) {1 p6 k; |/ ~8 ]6 `: E$ b
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {
2 @' s* Q0 G7 }; s" ` res[1] = res[0];
3 I9 T- q/ q8 T% L/ j res[0] = c;' [8 ]% ^1 d; v( O5 V3 d7 d( x
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {
0 ~% c9 G, T) o% E9 C1 I res[1] = c;
: E! s# j. s+ l- R" _/ C5 M }
& v3 S+ h4 ]' k% I \0 F: v) p }
$ k6 F2 W, Z+ o6 R* C return res;
0 \0 Z$ w; E) S/ O }- }. b, T9 X I3 Q
}, j: y, C' z& A( }
/ N9 n ~! w2 i# u U+ |7 z' o9 H3 I5 q: f5 b
【 NO.3 拿出最少数目的魔法豆】
0 ^- H: [% \% n3 H1 y
7 p; k1 M( Z+ }- ]8 ]+ ]% U* M解题思路$ u1 q6 U4 T* X8 s3 I
前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
3 i: q6 E" b- j% O2 N0 @( F
* e7 F7 \% d. Z7 y代码展示$ E, S; a" J: p, v D( A$ W! L& W
+ t: S; P* B0 Y+ _2 Z- o' ~! w
class Solution {/ S: [% Q( ]' `( z$ K& `
public long minimumRemoval(int[] beans) {
( ]0 v9 O4 [) p: |& y6 d4 R9 b+ ? Arrays.sort(beans);/ {$ v y/ H5 j0 z
var sum = new IntervalSum(beans);
8 j9 ^* }& u$ ]& V long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;
8 T9 a' N" }# Y1 d7 c% g1 ~ for (int i = 0; i < beans.length - 1; i++) {
- s! W" s8 J4 p // [0, i] -> 0; [i+1, length) -> beans[i + 1]( {/ y) i4 ] ^$ @, k$ i/ Z* j# K( m6 |
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));3 }8 i" R) o5 {
}
$ _9 q4 \$ \, |3 ? return res; O1 q+ K1 _' ]) v! g
}% @3 y) v) H3 Q& U# b! P' |
}! Q9 }4 L: J4 _% c% X! r- Q1 N
6 ^: L1 K* q& z8 y$ W3 P0 y
class IntervalSum {8 g" K$ f1 b! _+ J) O
private final long[] pre;* O9 X6 o% R5 ?, M( h s( A
+ r. Q: ^0 H" n public IntervalSum(int[] arr) {8 P- j3 `3 l) _& p7 o
pre = new long[arr.length];
f3 G: |) w) C2 b! P; \2 } pre[0] = arr[0];6 J* }* `, L5 E! H$ Z4 R
for (int i = 1; i < arr.length; i++) {
3 L3 f8 T5 y1 N2 z% u pre[i] = pre[i - 1] + arr[i];4 k; Z) n4 \2 ^
} \- K9 _4 ~6 P0 \3 l8 Y
}! X! R* a1 J3 D* k; Q
. j+ z, @2 \* G4 x8 V
// interval [0, i]+ a- l/ K" G& [5 b, b+ F! D
public long prefix(int i) {
: L$ X9 X" S9 |% ]6 o" T return interval(0, i + 1);
4 K- v( Z6 L; ^$ e, i _5 y } P) Y, s& a, j3 P G* n
7 s9 Q0 L8 ]" r4 _& m // == interval [i, length)
: V8 D7 Y: l" F public long suffix(int i) {! _) R* c9 s8 i7 e
return interval(i, pre.length);+ j; P9 d3 U- t: Z; f3 [% a6 [. n
}) `. }+ ]8 o- Y9 q: D2 \% E- w6 M
4 G) J2 B( l: I: R // [start, end)- s/ a4 p8 I, | t
public long interval(int start, int end) {
4 C% A8 p) D5 `8 {3 [* V# Q end--;. ^6 t0 u) _" ]0 s; H% W
return pre[end] - (start == 0 ? 0 : pre[start - 1]);
2 d& m9 o" h3 `- r; W+ b( |' M }
+ j1 h& `- B8 v( k; j}. P* V" b9 q2 e* D E
7 \, }* v9 `" N& T+ L( F5 A9 R2 |. t8 M( \
【 NO.4 数组的最大与和】
9 q0 S: d& X. m1 m' c3 S% W K, H7 d6 B- c+ j
解题思路9 G- o+ f+ f5 S5 y" |7 \$ y
记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和
R* G$ c1 N& s i9 ^5 Y& J4 l% k* I' W
状态转移:枚举当前数字放到哪个 slot 里面
, t5 t4 u& X: m: P1 E- m6 E$ A0 Y* i! m# W s7 A
答案:f[0]6 E2 E: K1 }0 `
- n; }: {% S5 p# ^其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字 }% e' [+ T3 l8 M" J1 q/ ~* O* t
- w" o7 [8 S f2 B& c) x' k
代码展示8 C* V8 h9 y' }: u8 L2 M1 f$ Y
* G% R8 Z, ^6 @8 R9 `class Solution {
9 E; {- W/ X9 n) u% B- D public int maximumANDSum(int[] nums, int numSlots) {3 g; H1 j( ~4 u$ i
( @- P! Y, I* O
Map<Integer, Integer> mem = new HashMap<>();
& W8 z( o9 c1 f% i( H return maximumANDSum(0, nums, numSlots, nums.length, mem);
" l* l3 _) ] Z( w# j }
0 x4 A- u+ P+ c* C3 N
6 o$ |. V) F$ M0 \$ B private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
* _' K' c6 E/ q1 a8 h0 e if (mem.containsKey(stat)) {
1 A0 E& R& N- o1 }9 g7 C$ t* g return mem.get(stat);
' s% E P5 e. t% l }3 L5 q: { g7 G! s& n; P
if (numLeft == 0) {
2 s$ R2 `% j- h1 ]6 J! R return 0;
" ]( h: a4 _2 |& x4 t- _- } }4 G! V$ l3 V8 r! f" ^& ^
5 J6 W" } ^, B( M: O int curRes = 0;) s. O: R3 `. ] S9 a$ Y
for (int i = 1; i <= numSlots; i++) {
* @: T* a. Z$ ^1 z' f int slot = getSlot(stat, i);
) ~9 k6 b, B6 z if (slot == 2) {4 `0 z0 m g) b! P$ s2 g3 K& Y& u
continue;
9 \5 z# m+ |9 @/ F# z$ X }
4 \/ g5 b" p/ t3 V int and = i & nums[numLeft - 1];
3 r& i3 H+ Q2 m3 ?# @& j q+ d int stat2 = setSlot(stat, i, slot + 1);- P) m2 h' Q) z+ }
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
* p& W; T* t" @* @7 a }
( i' O2 D4 j' n
5 N l0 x y. T4 `* H mem.put(stat, curRes);
9 i' v, [* I; A. [+ X B. I return curRes;
5 [8 z4 n# g$ r4 O }
# z, M4 Q3 P$ W8 v" D- ~+ O7 |. o; I/ q. I @) ^
// i start from 1- V& g1 ]$ ~2 K2 D! h# u4 U
private int getSlot(int bits, int i) {
" Z/ `1 X" {1 `2 ]6 M- m9 L int offset = (i - 1) * 2;
% B( A6 h9 d6 P return (bits >> offset) & 0b11;' U; B$ s1 F4 H/ C$ s! k" K) r
}
* j' \7 w4 Z, X7 Q; \0 |# h0 _7 j( t/ q2 g4 A% K( e& |
// num = 0 or 1 or 2
- A9 y2 `" v, X/ |; E. K0 M private int setSlot(int bits, int i, int num) {+ p1 S. `3 w9 X
int offset = (i - 1) * 2;4 H0 o& y* L, w" l
bits -= bits & (0b11 << offset);4 H- g) R" Q) `
bits += num << offset;4 [( p5 Y( p6 R3 N
return bits;
: ]" K, N F+ [ }
, x6 T, S- Q2 V% t' H% ^} |