登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】: ^8 @0 E. B$ H0 D
3 S' H( ^% E" i" a7 H解题思路
# K. ^8 {9 J7 Z: J( ?3 K. F签到题,模拟操作即可。8 [. t, ^# M$ M# E
) L: _* z r& L# w: Q代码展示
" V% J0 L2 S3 w3 D4 C* O* W8 N% m; w) S, ?! k
class Solution {
+ ^) K) V# {* T public int countOperations(int num1, int num2) {: N x: t6 R& P H$ Z- `
int res = 0;
; J4 R4 k/ Z; Y4 s9 h' X for (; num1 * num2 != 0; res++) { |6 n4 S5 [0 Y! a) O
if (num1 > num2) {2 K0 J4 o: `3 M
num1 -= num2;, y4 S) D# |; E e+ M
} else {
. W6 z; g+ x" _* E {9 I+ f0 G num2 -= num1;
* b( H5 e. w' ^ }
) K5 C! b# c2 R: m5 v }% a3 q; Y6 Y+ N5 w
return res;2 A; s' \7 |: v/ R- m
}
, U5 B& E# J0 |1 h+ |7 M/ D}; e) ?5 s% W7 j, ]$ T- N$ M
1 Z" p4 I$ W5 K& S; a; G% D6 Q: v0 G# a/ p2 j
【 NO.2 使数组变成交替数组的最少操作数】5 l/ {8 \" L& w: M
. |$ }0 u# |% N% N) G" u M1 G
解题思路, B5 C* v7 Y8 u! z' d9 C
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。% \7 ~& S5 Z6 V4 Y6 f
! c! x: y1 A; c1 N. o: F
代码展示5 _: a; Y4 A3 _% [- S2 h
5 _( K2 _# b; v0 Fclass Solution {
' f f g4 M# m1 x! o" N9 A public int minimumOperations(int[] nums) {
% @: b* R# e8 f& }; C" \ Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
4 @( h$ z, @) |* T! Z Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数' z5 N. g1 Z9 `1 e m& |
for (int i = 0; i < nums.length; i++) {
3 C' F" Z/ r7 [' K if (i % 2 == 0) {' U* O, o4 s. }& _
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);
}$ G( x1 X' P! W* b! R } else {
7 W5 s+ K, T7 C2 G: y8 j cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);; s" J3 _# O+ Q
}' ]( q- y0 Q- i# z& Z' E
}
/ \7 F3 j8 j4 F" T6 W! A; f int[] cnt0Max = getMax(cnt0);% _2 R; ]' Z& I/ j5 R7 G& T
int[] cnt1Max = getMax(cnt1);
; ^& v! a5 U0 A, i4 _( @% C3 N. e if (cnt0Max[0] != cnt1Max[0]) {
/ @5 @6 T5 g' Z+ t$ V1 M return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);3 E# \4 U: U4 S8 a, {
}, E4 R" n6 d* I" y1 t v; B4 Z) P
return nums.length - Math.max(6 A6 c% Y0 D( B; I' ^5 W
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
# t& a) k0 E; ? cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)4 e3 O3 E: w% Q0 r& |- a' P, P
);7 g5 V; e4 r" z
}4 f$ G8 l: P! ]* o6 S3 d
( i; W- ?. k% ^" j4 f% w
private int[] getMax(Map<Integer, Integer> cnt) {; Y% a$ n) H$ g5 C8 F7 c- \
int[] res = new int[2];# j3 y- d# ?/ Y% T
for (var c : cnt.keySet()) {
4 e0 w1 T, \8 Z' | Z) v if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {! o' C3 m) C9 w4 x) ]0 e, m3 s/ ~
res[1] = res[0];$ r9 S1 ]7 O: z ^; V% H' W
res[0] = c;6 G. Z. ]7 b" X/ o) Q9 g
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {
. ]5 U8 ], S6 L- e2 e } res[1] = c;1 W; Z. e( h; n# J3 M5 _
}
* n( F B2 [1 `8 U8 H: `/ | }( w4 o. @/ p* u3 {' n/ Q; G/ S. f
return res;, R" C2 ~& D! c2 |) O6 o
}: V$ c: a* y! G V
}' N5 p2 e6 q% }
, W- Q$ S1 e8 O5 n( y3 l2 w8 b; z4 j- ^) a
【 NO.3 拿出最少数目的魔法豆】
0 v8 R8 I& x# \, h( @, h& v* r1 j1 C; }1 Z
解题思路
" V; W6 J" {4 v% m前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
- ~4 s+ \5 U0 S) L5 T
4 I1 x7 x0 y2 }: f/ V代码展示
. J ?. [& e( d9 ?. [1 H& Q
3 y/ i1 |2 s, G& l: Jclass Solution {
/ C! U* x# k5 } h6 K9 ^7 ] public long minimumRemoval(int[] beans) {
! X/ y$ M$ H, z w1 o8 \1 B/ u- ` Arrays.sort(beans);
C3 b+ I, i1 ?9 d! D1 Z var sum = new IntervalSum(beans); V+ z4 c. j# Z! `, s4 V: }
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;5 `+ s7 t4 o6 |& X$ ]5 Q
for (int i = 0; i < beans.length - 1; i++) {+ M, h. H* O; z0 w5 P! `
// [0, i] -> 0; [i+1, length) -> beans[i + 1]6 f1 z P) i* B+ A8 K$ O( s
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));6 V% u0 b5 ?: s7 s+ ]
}+ ]: n! J8 i9 U7 f
return res;
: G+ d$ u% T9 K: [( T }& o/ Y" a. R( E b0 J: V
}: s4 a, L4 R! I. V1 f
8 f. ? ^7 r$ p, b
class IntervalSum {! i ?$ v: Y' X7 Z o
private final long[] pre;( M3 v/ t. q5 b- q
$ y# o0 P. b( [5 r public IntervalSum(int[] arr) {6 y, b- L! O9 v2 C5 x8 k
pre = new long[arr.length];
$ n& q2 I5 O5 H' v pre[0] = arr[0];# h4 A$ w! |! R8 ?: U/ i4 }/ G
for (int i = 1; i < arr.length; i++) {9 k6 i4 _) O) p+ z2 h. y
pre[i] = pre[i - 1] + arr[i];
, m4 z# p3 t; ~" ?3 P5 P. G d$ Z }& w( x! P. }" ^
}
% W" a- w" @8 m4 b7 z
2 }( g/ i3 v1 _; H9 h6 G // interval [0, i]" ]/ w8 ^, h* a A
public long prefix(int i) {
, M- I% q1 u/ O- m' C return interval(0, i + 1);/ e0 s- |. Y9 ~' W9 Y
}
+ s# g1 p& V1 V, z
# p. d8 s( y3 ` // == interval [i, length)4 C8 a$ O B3 X
public long suffix(int i) {
7 k5 O+ j. w" F7 P return interval(i, pre.length);
* d9 m- U5 x! M( L8 j" K0 c3 [& I- j3 P }
5 h5 X. r: i% P& y C8 m0 O$ D; s$ u9 `* n; X/ W! j4 q
// [start, end)7 z# s! |6 u$ A( q
public long interval(int start, int end) {# q& j( U% Q) c
end--;
, j* }4 [( y& j3 [0 w return pre[end] - (start == 0 ? 0 : pre[start - 1]);# `# }% k* P6 a* J0 A. u
}
2 P. \7 A" K& ^" v e& Q( H" h}
4 I( g9 `$ D& {& [' r. }$ [ H% E7 \ {1 x
4 b! {, A" H& k" o ]
【 NO.4 数组的最大与和】- x/ \" V$ A( w! ~; M8 L
( Q8 s+ p8 y1 p4 @, Z% l" t解题思路7 u A2 O1 E1 y+ I
记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和3 I( y p4 `% g. Z
# B% Q, \9 w- z* S: \1 B5 \' z状态转移:枚举当前数字放到哪个 slot 里面
5 A# d) z1 g7 J: z z! M- H: P& q( { l
答案:f[0]
3 H# }1 J* |! P, K$ v: ~0 O' C
" s- F+ A# x! r其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
1 ]) z- X0 `1 o3 I, r5 s' Q: z2 Q: T7 r
代码展示
1 p3 F a. L% V/ M: Y9 z" S6 Y
5 R: K. F+ q* h$ h( iclass Solution {. d, \5 m* \2 f( g( u9 D
public int maximumANDSum(int[] nums, int numSlots) { B: J6 D T0 m O! ^3 t2 d& z
0 _$ }- z; |6 h/ M
Map<Integer, Integer> mem = new HashMap<>();
4 Q: L: \7 Q% B- ~! f7 c1 q3 e7 U. | return maximumANDSum(0, nums, numSlots, nums.length, mem);
" w+ A# n& \& w }8 G9 c i0 R) G. d/ ~; C7 J
p+ S- ?1 {1 h private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {" q# \& O2 k5 `% P' _
if (mem.containsKey(stat)) {' C' ?$ S2 N) p2 w; ?
return mem.get(stat);( @8 K$ ]* Y- M1 h/ b- m! `3 v2 o
}- X' ^1 ~, o9 F
if (numLeft == 0) {' w9 ?* L2 l2 Y! l( l- j8 E' Z% K
return 0;7 p- t( d! `1 f# h
}
: W; V- ]. h3 _/ O6 c
9 C9 N2 P1 |* V6 F& `: x5 E6 u7 a int curRes = 0;3 a6 v' s! u3 ]. n
for (int i = 1; i <= numSlots; i++) {" N" C, z* v8 a/ R4 R* M
int slot = getSlot(stat, i);
' ~% B% n( I& p" L2 l if (slot == 2) {
9 r/ `# U6 D" Q5 B& _4 ?0 t4 Z continue;3 u9 s6 g [* p6 h: ]5 v" E9 L
}8 O2 v! M% W) f# _" C$ q
int and = i & nums[numLeft - 1];# P- K3 d" x% v+ ]1 u
int stat2 = setSlot(stat, i, slot + 1);
- ~# I/ L/ M( h curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));) s( n" B: d4 o
}# L$ |# T' I* o+ [& O5 W: u( ~7 l0 x
h$ v5 P$ L; N2 C& J9 \
mem.put(stat, curRes);) O7 t# Q- U+ ], l% m
return curRes;
( Z( P8 f! ^0 g% Z } t2 @3 X, D- m1 T* h
4 e/ D+ [1 K" r- x! H // i start from 1& j& Y; v& \( |) k6 `0 Y2 `
private int getSlot(int bits, int i) {1 p; e' V1 \# \
int offset = (i - 1) * 2;
+ x+ G" n; n3 y8 j( B return (bits >> offset) & 0b11;6 w8 _) j5 B5 \. F
}
9 M1 k3 B5 w) @ k. r9 {0 w. p/ }4 f. b; M' j# p' Y3 M7 Y& W
// num = 0 or 1 or 2
* y$ i: n# ]% x, F& v& B3 Q" S0 Z private int setSlot(int bits, int i, int num) {6 q/ R; W( N7 [0 D4 F6 M( u; ?
int offset = (i - 1) * 2;
6 R' P$ ]/ T% y$ h' o+ U9 l$ j bits -= bits & (0b11 << offset);* C' g/ c& f$ _( e: `+ o# x
bits += num << offset;% f) q* I2 p' }% Q% o( G, o
return bits;3 A( g/ F3 g0 w7 T' W
}# z3 c) k$ R$ X: t
} |