登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】3 l5 J9 _! e, t4 R i: v% z" b0 N
8 k5 X1 Q8 r7 l. N7 e" h* W解题思路2 V8 o5 e6 h( S
签到题,模拟操作即可。
8 k% F, L& ]" y. ~6 s- b
/ v) B% j4 P1 Y0 K" F代码展示* u! g0 u% T/ K) h+ ]9 X* G2 @/ P
, d1 ]+ z! }* s+ L- d9 B2 aclass Solution {- m$ H7 i8 p9 [9 k) U+ H6 }
public int countOperations(int num1, int num2) {5 B0 t5 p4 o* e# c
int res = 0; _7 J9 [3 C0 b
for (; num1 * num2 != 0; res++) {
* b5 u* E: x9 O* c if (num1 > num2) {/ C, T q* C- J# x" s
num1 -= num2;3 @1 R) g1 l0 [7 n/ M4 w" v3 \) U' O
} else {; e' d0 Z1 _; c# j
num2 -= num1;
4 I( b' w; h8 x }& K% y) {% p; E
}$ `5 W* I2 O X* L( K4 t, x9 M
return res;
% }& J1 l$ P% q# } }
) o9 @2 A$ K' u2 @" S}8 n! X% n" f2 W7 ?+ J
! I+ F5 A, Z* \& q
, L' w- _- q& h1 U【 NO.2 使数组变成交替数组的最少操作数】
+ U' C6 \" z1 y H( B v5 P
/ u. W) i9 j8 d6 @0 {; x解题思路
1 _0 n& b2 j7 C9 E% I$ n统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
6 n4 M$ e. C, \6 v, v. ]/ {$ e2 [1 V, A x' L7 C; ~
代码展示0 J. A* K5 C. k& p5 u- s
~8 J- u, l, z6 z& V# r. Z Xclass Solution {8 |4 r8 n1 N$ J( M
public int minimumOperations(int[] nums) {
9 g& j8 ?$ e0 k Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
2 @" P' n* S5 n% e7 |3 F$ X l Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数
/ Z2 Y9 V- n' W for (int i = 0; i < nums.length; i++) {
9 N/ v$ a& [( @% b. C if (i % 2 == 0) {( c% R, i$ ~* u8 Z' P/ `
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);- ?0 D. o7 S( }$ I
} else {1 y* r/ i& B4 ?! X$ R. M
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);$ e5 M+ M0 Y& t( j. m1 I1 t" d
}! N. r$ @) C- x
}5 Y) w8 d. b/ ~! |: z0 w f% T
int[] cnt0Max = getMax(cnt0);; f) K' V/ u: o* f+ K& |
int[] cnt1Max = getMax(cnt1);
; @# j- n; A. X+ B& L$ y# I if (cnt0Max[0] != cnt1Max[0]) {- B4 @* E1 `3 f. q, X* e6 m/ o
return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);
+ w% Y/ ]3 \, H4 r" q }* F' p+ c: k' ?% ^+ P
return nums.length - Math.max(0 a# a% I: W8 g3 y8 ] [1 v
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
4 u6 K- H& a: z: q4 o+ B3 X cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)7 `8 D! h/ F+ r9 F+ O5 n/ W( u8 v
);
0 t& s" B, |" w7 Q! `3 j }
4 [7 \ N2 s4 K6 R9 d/ Z9 |6 ^8 o* d- n9 z/ J/ f5 g
private int[] getMax(Map<Integer, Integer> cnt) {0 W' H8 W4 Y6 D( [! ]4 J: H8 R
int[] res = new int[2];
/ {! @9 p) i! G9 S6 x for (var c : cnt.keySet()) {
* \% D/ K$ R, Y+ a3 g if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {( c( v; Q- P" U' v! n3 w: ]
res[1] = res[0];
0 p/ @ _( G4 v: x) W res[0] = c;
2 x- m3 d& z. a" ]9 t } else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {
' K8 q* |( T! b p5 G9 J5 V5 f res[1] = c;5 g7 X2 W. u- n" K
}4 y/ V! x' ~7 ~
}
& ^. [/ Q6 j; l return res;
& W* [# y' C9 x W. o }2 v, j5 f$ o% `
}( r' D& O% q( v6 ?8 H
* t' ^- p) ?0 t* H0 L$ p3 n v3 L
0 x3 w2 M9 m$ y) }- d7 K
【 NO.3 拿出最少数目的魔法豆】
9 A- P r0 i) Z, R, e, q" {! h8 z/ ~7 s' m" Q0 Z0 J/ D$ \: n, A
解题思路
( ^7 }, }% k+ r# `) J前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
{, F5 B/ C: s6 t1 V% L% o4 z5 f- p8 v4 n+ l. C
代码展示
6 W$ E, n% R" H, H9 j+ ]) _- A6 J) E; v6 w* t+ w6 K
class Solution {" i B4 ^' q% e
public long minimumRemoval(int[] beans) {2 Z! E0 g1 W$ X- ], w: ?
Arrays.sort(beans);
# y8 P8 r6 S3 A var sum = new IntervalSum(beans);
9 }( ~! H/ o, W4 ^. q- D long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;+ l% j- ~# e; M$ ?7 R
for (int i = 0; i < beans.length - 1; i++) {- S; c* x& O& F2 Y* D. e
// [0, i] -> 0; [i+1, length) -> beans[i + 1]; J7 @# }* O9 Z
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));
. v: P( \1 b+ B; K5 r }
; z6 }! B5 r/ p. {, O return res;
2 a9 O7 g/ V9 V' d/ x }
) t- K6 z+ c7 g4 i1 ~- q* c, s' ?}
; n; h Y3 t2 _8 |& [) m9 V& S3 }, H6 L+ e6 O
class IntervalSum {
( p$ C7 V/ F9 ~9 m! S. ~$ B private final long[] pre;! H' K! r3 i% U, H0 [
. y( O$ v' d5 L. V4 H( k, B
public IntervalSum(int[] arr) {
% F4 g" p$ L8 i) i+ N& W pre = new long[arr.length];
9 b6 m9 {( V" B6 J f6 X; t pre[0] = arr[0];0 R( N, W" i5 K, V/ O* M8 ~; L
for (int i = 1; i < arr.length; i++) {9 k- k4 J0 D5 m" }+ {; h
pre[i] = pre[i - 1] + arr[i];
: D% \3 h. A/ R& F K& e) ^1 R }" ^& h# ? u' Q( G- ~3 o
}3 O5 V8 k/ D0 O* I2 p; N9 s: n
- |3 V X1 N9 l. X$ q. B9 B7 t, a, a: q
// interval [0, i]7 N8 }% R. L. h
public long prefix(int i) {6 g L% ?) m f4 t/ v6 S
return interval(0, i + 1);- P; N0 |$ s( I- ^1 g5 a$ ?
} f* N, k B" x0 X
7 K8 x8 y5 J O9 n: ?9 U N( ?
// == interval [i, length)
5 o$ H6 b5 c, o4 z) t; v public long suffix(int i) {1 O: L2 H3 k( O, m$ H
return interval(i, pre.length);; E; R$ p' Z1 p- z
}' w2 t3 C0 T/ D! C2 g/ f+ g
: d8 }8 k l' Z4 M& c# ~4 H // [start, end)
% {! k0 x" g r0 u5 f8 D/ E public long interval(int start, int end) {
. K4 {2 V1 f! q; ]2 K2 J1 r$ s* {2 P end--;+ b/ N" v, x/ t6 Z/ `
return pre[end] - (start == 0 ? 0 : pre[start - 1]);3 D- g9 f# K6 J- r8 u) z
}) Y2 N" w/ P9 T! R/ m' k
}4 J! g( P9 t# t, Y& }1 ?
% ?) Y4 w+ g% m: j+ o! B1 r* g
f' T# g# T2 R# q% h【 NO.4 数组的最大与和】2 u% J8 l9 k8 v0 z3 Q( G
" E- r6 y P) B解题思路/ m2 ?3 b9 j. C4 v# L
记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和
6 A1 L- p/ q5 z9 H; ]
$ A6 y- E$ b; _3 L: L( q* C3 o状态转移:枚举当前数字放到哪个 slot 里面
4 T% \: g/ a+ i5 b- _: g: U/ q
+ ^5 `3 h' v4 t" ?. b$ F答案:f[0]- d( n/ ~! }- ]4 A1 R7 y$ }
& F( N' n# X+ w
其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字) h9 U" S6 Q* U" l/ @* M
, {. H6 T' h2 k D* r2 j
代码展示7 N2 o' J2 q) Y" D* |
/ c! d' W' ~+ }
class Solution {
. O- D+ r# k- D- B6 V% i public int maximumANDSum(int[] nums, int numSlots) {
" A; _( b$ ?$ ?/ E Q& ^
3 N5 T3 B0 B6 l1 K Map<Integer, Integer> mem = new HashMap<>();
5 w+ z1 F, y& ~; @0 g return maximumANDSum(0, nums, numSlots, nums.length, mem);/ r" q7 Y* Q1 h& a, H3 c
}
8 }; b# |% Q9 D/ U8 e5 k# K3 v3 K# R3 t; L0 o
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
6 A. G" `. h3 j1 ~ @& U1 i if (mem.containsKey(stat)) {
) ] p" D/ r$ { I0 w; J% X return mem.get(stat);; m+ n6 L- |+ ]6 a5 G
}& u$ H0 z: r6 J, G+ `
if (numLeft == 0) {
' C% M7 P# L( V1 ?7 L+ [ return 0;
- q- e" J! F; `8 z% o }
( P; q8 E J/ D, C( T; T
; T* Z" N9 \( T/ \. v6 {& { int curRes = 0;# l; w$ g7 }/ e6 V, h
for (int i = 1; i <= numSlots; i++) {
/ d! h9 D" I5 T/ }+ W# ^ int slot = getSlot(stat, i);+ S" n( Z* H! `6 t
if (slot == 2) {
. Z1 ^) t i" m4 ^ continue;
3 v9 t+ c7 G ^4 K }
. t! y+ c' |7 G7 s3 G int and = i & nums[numLeft - 1];
" t5 N% @6 S, x( H% d6 [ int stat2 = setSlot(stat, i, slot + 1);3 d: e6 L5 i0 [: S9 A' E5 X
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));" a4 ^; @6 o5 ^: P* N
}
' G6 w3 ]1 F4 e+ H
; s8 a; X4 `4 J7 V9 E- ^$ r, M8 j mem.put(stat, curRes);) n; U) f0 u/ S2 p
return curRes;* Y. a6 l/ a3 V3 R' D, O
}
5 f5 h% ]! a' O/ I0 T5 Y- }9 @2 X
, o3 t- B2 B2 N. A9 f2 V // i start from 1
. H, Z' c! \0 ^ private int getSlot(int bits, int i) {
. }& f$ [1 F5 v# [ int offset = (i - 1) * 2;5 ~( u2 f% W/ d/ q& \4 Y
return (bits >> offset) & 0b11;
& c* ?, F' K$ x) S1 B9 H8 m }0 Y8 w) Q f H n& ~0 w( r/ \
( r: e# T% d; Z) L // num = 0 or 1 or 2
: e" l5 C7 H* _* A. p, m, y- _ private int setSlot(int bits, int i, int num) {
1 O7 c) D1 F, q int offset = (i - 1) * 2;
% `4 S( n- x; o8 S6 S bits -= bits & (0b11 << offset);
3 G' e5 E# e4 K( X( M bits += num << offset;# k( ~1 C/ @+ q1 F' |& b X2 R/ [
return bits;
?+ Y5 n( x1 E2 y% } }6 G: ~% B6 P& Q! N+ ~
} |