登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】" \" v; f/ H) H5 Z; r
3 S7 z" F* f3 i4 W2 p解题思路- P1 i( I8 s3 H) I3 f
签到题,模拟操作即可。
; S- b( X. y# Z K- K: F+ {. ^& l& ^- g( `% d$ ]3 }
代码展示
: [" H/ v* D" |0 T9 u1 q; y& h) C" x& B2 t
class Solution {
Q5 W8 G( c6 u% R) q1 a7 M public int countOperations(int num1, int num2) {
5 }+ u0 y6 J( O# r% b int res = 0;
9 L; [' w. {3 i/ y for (; num1 * num2 != 0; res++) {2 @. Q2 F/ x( ?; V- E: X4 q% t
if (num1 > num2) {2 J2 ^: _: J: Z+ T. {* e4 L
num1 -= num2;" c- @) E; D7 A' W+ U
} else {
1 [0 ^0 s9 z. W6 B: ] num2 -= num1;2 j6 s( y: D& _1 `5 `
}8 |0 \' l% K. @
}" p3 ]. t) o4 X7 w' g' ?
return res;. i2 Q& u- Q& v+ I4 d; E D
}; i) u$ W2 T# y2 n
}/ y% F5 k. d% n* a
+ V8 V1 [1 u# h( V( Q
" G! ?( b1 Q/ M0 ^【 NO.2 使数组变成交替数组的最少操作数】
2 l, c' @5 W# q H8 P, X4 T8 @0 z0 w/ T
解题思路
: F; C0 o i! J统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。! Y+ [; X" U/ c3 W
$ [! F4 W# s+ d& Y+ {- \# m
代码展示
2 u9 V% q1 B* h: Y
) V, ]; z' `4 [8 F! g9 {class Solution {+ ^: b) b: M# [# P% e' R7 [
public int minimumOperations(int[] nums) {
! O# G3 i+ x8 b# w Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
# ?6 F5 Z& U- F. h2 u$ G& N3 _ Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数$ z0 |& L/ N; m2 u
for (int i = 0; i < nums.length; i++) {
9 \. S- _; P2 \+ I% P if (i % 2 == 0) {3 a3 C3 C0 [/ U0 V; N. A
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);4 S; ?+ t2 Q. N5 X
} else {2 }1 n$ T) W+ S0 F; q! Z9 [0 u: ^
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);+ k1 A" w! D4 F3 f6 ?
}
0 ~$ r5 B) |# m( o6 x' q0 b, W }! P- K! |+ g6 U- f6 \8 f
int[] cnt0Max = getMax(cnt0);
`- U$ w1 R4 Y! x/ y int[] cnt1Max = getMax(cnt1);/ @, ?& r1 v* t4 Q. F
if (cnt0Max[0] != cnt1Max[0]) {
# n. J- O4 N1 a. U* Q, Z* N return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0); |5 b% J. L! G
}
/ n/ x! u( _1 [0 z* D; J return nums.length - Math.max(
% {& \8 b8 F+ h" S; A cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
( e5 r4 c# P" R7 w7 H cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)
5 U+ g# ~. l' J );& f0 X) O. \2 o" p
}: n3 G! k5 o* Q/ {6 o- s' _
2 J$ }" H- F2 S U& Z: n4 o
private int[] getMax(Map<Integer, Integer> cnt) {
. P6 ^8 w5 U! v# l int[] res = new int[2];
* X, j- q" `1 D for (var c : cnt.keySet()) {0 y4 \# d) y8 ^. u! Q& Y k
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {
# u% o5 M1 x( y1 S) B+ F% h res[1] = res[0];/ ]6 Z( r4 t4 h! E0 A$ z/ N9 L3 }. ?
res[0] = c;( p4 v& N) O( [, n/ Q
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {+ q \) [" i$ A
res[1] = c;7 p$ }; z4 x) K, L' K! R4 ~: n
}2 u, [. w0 s U4 l: M# g
}# b' e9 S- o# w
return res;2 M3 u$ I6 L6 N1 K# i& s3 e7 C
}0 @3 n) s' `$ S" L9 H6 o, I
}6 I3 b; ~6 l+ w- @+ o/ ]( V
* H/ ^9 d3 K/ o2 F G
- R2 Z2 \$ Z# J( ~' o" [$ U
【 NO.3 拿出最少数目的魔法豆】
, Z4 m$ `) a; v; T$ W4 H) u# w6 N( x. j( ]2 l
解题思路
3 X# [8 a" I! P7 S+ j前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。( {9 y1 E& G3 A7 j
4 {" |- O, |' K- e q( S5 x代码展示
) o8 o |$ E9 q3 g& `& }" q3 ~! |% `+ a0 \4 O4 R" a
class Solution {$ p* |6 r r$ n9 ?
public long minimumRemoval(int[] beans) {
1 Z1 L7 @! z( O! |1 X7 J% Z Arrays.sort(beans);
- c3 i6 b$ h: O& b var sum = new IntervalSum(beans);& x& D8 s4 y3 X. r4 v. E
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;8 L0 {) o; |1 [( [, B* [
for (int i = 0; i < beans.length - 1; i++) {9 h7 ` P/ N8 y6 h6 z0 v3 v( k) k/ \
// [0, i] -> 0; [i+1, length) -> beans[i + 1]8 r2 E; P( V, ~/ N6 e* y& J0 q+ x4 E
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));
* G0 b7 F/ `2 F8 H" V/ C }
5 [+ @# ~0 d6 a& [3 G return res;) x% K! e7 ^: r1 I
}/ W" a5 }6 H0 q: t9 L. g
}7 c1 m' w1 V6 s/ I% c
% M, p0 j% {! T( v: |class IntervalSum {/ E+ W4 T6 t4 H" T6 I" T8 W. H9 w
private final long[] pre;" L3 O2 B# h' [9 ^
7 p$ m3 Y0 U4 _ public IntervalSum(int[] arr) {
' S( Y( Y/ l% B* g pre = new long[arr.length];- h. K5 c3 d3 S: O3 k
pre[0] = arr[0]; s1 b9 q5 a$ [3 H
for (int i = 1; i < arr.length; i++) {
) g( x+ D3 _+ B" { pre[i] = pre[i - 1] + arr[i];' x7 o5 C# a" e; B
}
+ w& O: C/ ^$ ]4 |/ Y3 L0 q }
: C* y: g: X* z9 W$ D$ i0 w2 I9 ~- _5 c- e
// interval [0, i]
; \$ S) U3 \4 v, d/ V public long prefix(int i) {
0 t- `; d; U* ?: [% `4 H return interval(0, i + 1);
& e6 {: v, p) c N$ p1 l! J: p' D( y }0 ^* B( r* I2 | `- P- O0 O
8 k2 V* G% m4 H" R // == interval [i, length)
3 r1 v5 D+ @7 h8 T8 L public long suffix(int i) {
) ]1 d5 }) y( H: b1 Q; g return interval(i, pre.length);, }3 E+ q! {0 g$ l0 G. R4 D) O
}
) f/ P. S4 ~. s: ?% R7 u# O$ n' E. H
// [start, end)3 s* Q6 E0 d" ^7 X+ o" C8 M
public long interval(int start, int end) {7 g) X5 g2 X, @! Y/ A/ l
end--;
% Y6 G# P3 Y. V( X return pre[end] - (start == 0 ? 0 : pre[start - 1]);
7 u7 I5 c8 J1 d1 _* ` }
& [3 [8 c) h1 b' r}
$ {& O. H+ k3 Y
. |' m9 n J: s8 k, J6 l, G A- }! ?; q; P% W a
【 NO.4 数组的最大与和】 R. ]0 S" K& ^* D! Q7 w7 d
: m7 P( |* X9 D
解题思路
# ]. o5 E- x# {+ m8 n D c% O记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和% t+ W+ @' t, j8 S- y
0 D W' t2 m1 e' X( q1 S" t% b
状态转移:枚举当前数字放到哪个 slot 里面
7 ?5 ~7 y+ m. u8 M# g m: z, F' ^8 y9 R* w+ M4 F4 Z
答案:f[0]
9 A9 U, @3 d# p8 S0 n
* D! e* O) }5 I其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
6 @. @! H! x- l9 t" b I& {( ]) T4 U# ?
代码展示
/ y' b& \6 c/ T# }5 W4 V+ E
5 D U' m2 q+ d h' bclass Solution {6 Y9 D2 b; N3 b- o( o. }: v
public int maximumANDSum(int[] nums, int numSlots) {
/ R$ i8 l- x. G% c u( O: e. C4 H3 Q1 Q7 }' z* F5 W+ F
Map<Integer, Integer> mem = new HashMap<>();6 _, S0 M- w2 L. V' N* Y& y" k
return maximumANDSum(0, nums, numSlots, nums.length, mem);0 E! l+ o: g! G! F y( C
}" F4 ~: q4 G1 o5 t/ G3 T7 {" c
- y; v% P6 p/ c O2 Y+ G {
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
0 M; q( [3 g+ h6 n if (mem.containsKey(stat)) {" s3 Y7 |( R) j4 R3 L( q
return mem.get(stat);* P; I2 l5 K6 e5 o/ B9 I
}
# q n4 V0 a ]# [ if (numLeft == 0) {- A4 B/ {$ x- q& ~, D3 [ a& J( H
return 0;
' f. J" d# E8 M8 S+ i }
# C: |# u- c# s# h; K. \1 X: B& |: W+ i6 q$ t0 h. y3 f% r
int curRes = 0;
0 o8 a' m- g! n9 \8 @ for (int i = 1; i <= numSlots; i++) {
\2 b6 f J" l& A4 N% h) |6 C int slot = getSlot(stat, i);
; D( L1 {* v! _ if (slot == 2) {
6 g1 Q: L' ^/ c! o) t" ]/ {/ l continue;
* d' R7 f3 V7 d }4 p, x( m. }/ t2 B
int and = i & nums[numLeft - 1];9 @3 T* Z$ n( R* ~1 ]" b
int stat2 = setSlot(stat, i, slot + 1);, I5 a; g) Y& H1 P" o, j3 L
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
, \2 h M' O8 E/ X7 F9 q) U }
+ A0 m' p5 b- R( t9 c8 ~* p9 E& C A, _4 E" _, U! [
mem.put(stat, curRes);# W8 x; Y- c( `3 x
return curRes;! o. ]9 M: Y& C6 ~* n9 W" n
}
( P( R/ D. }* U2 u3 e+ q0 b* h7 D9 @8 Z
// i start from 1; S. c7 e0 D ~1 m! w
private int getSlot(int bits, int i) {
2 x3 H& Q9 K% b2 x$ I, e0 Q int offset = (i - 1) * 2;8 y5 U; [ i- a" \6 Q
return (bits >> offset) & 0b11;
# t+ U, ]8 v7 h1 c% r }
& Q0 w X+ u. L
1 N5 N1 r+ t) T/ j // num = 0 or 1 or 2$ E0 r8 D6 E4 p" V
private int setSlot(int bits, int i, int num) {
9 C9 e' z. v1 s" Q$ J int offset = (i - 1) * 2;# `6 F) F2 `* a* V/ _& c
bits -= bits & (0b11 << offset);! [) p% \" b/ V0 ?* T7 a L( p
bits += num << offset;$ M `4 D2 M% H0 L7 r
return bits;
( p2 F( _6 j. F) D% x; q F+ N1 h1 s }+ p$ j k+ t3 v1 ~, @$ C3 N2 y
} |