登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】
! C' G# y j7 I# y( s& n5 _# [1 k1 Z; o. Y
解题思路
/ ~1 J. y9 [, F: M3 F+ U9 U3 L签到题,模拟操作即可。' w' W9 c# X z* F( q. r
" r. C% @$ U! P代码展示
! J, b% F; _( r" v1 p/ Q
$ l) R2 a( y9 C4 J3 d! r% E) pclass Solution {6 e1 n1 Q" O2 i' G% H
public int countOperations(int num1, int num2) {
9 g$ O, L. U' E1 y7 F2 e# Y% ? int res = 0;! T/ k6 P: S9 B2 {2 T
for (; num1 * num2 != 0; res++) {# G7 s1 U9 C$ d% W$ P8 _9 l
if (num1 > num2) {
7 o; G6 ]. W: N- E num1 -= num2;- M! ?, y8 h) ?1 z C' I
} else {
1 L9 a& e, \* o- l7 H) T num2 -= num1;0 w2 s2 } X# X0 X% t9 Y
}
* v! x8 ]5 m u }
; a' z" K1 J/ ` return res;6 G+ d) L0 V$ Z8 }$ g' w! D
}0 p* H5 ^) ^- V( V8 J8 i& {
}: e; l* b. [) o* \' u
% K( G' w2 h& ]. {
2 g( Y g2 B! }5 Y" y+ j【 NO.2 使数组变成交替数组的最少操作数】- H) t, r5 O# ]
$ {+ O5 P% [# Q; _. ]; L% p/ F解题思路
* ~0 s# k f7 P+ n) P8 s统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
C- [% D. X7 t5 d, b" l8 L; \& v4 a( s% d( V8 a
代码展示
; q6 R$ ?% f3 b8 E0 [" q6 _
0 X: P$ b+ G/ b7 j% V9 `: q& wclass Solution {* I4 J. M4 Y. R+ e
public int minimumOperations(int[] nums) {. q) d3 C- V' t' V1 q7 M
Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数1 z& }# x9 L: C L9 v; U+ x
Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数
. p. C7 @! U" I for (int i = 0; i < nums.length; i++) {
7 G E0 M5 O2 c0 \$ H if (i % 2 == 0) {0 l% b. ^ v6 i- w4 `7 z2 s% [
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);: H+ c$ j( r7 t3 x7 N1 h
} else {7 B: u9 O/ F/ _
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);! W, v% o$ Q2 @/ g' m' g
}) j9 F7 I/ e8 v- o U9 m$ B6 n
}
2 [5 w# I9 _; l& T int[] cnt0Max = getMax(cnt0);
" l o! D* U: _- u9 D int[] cnt1Max = getMax(cnt1);
2 h0 o9 L3 l, B+ ]/ a1 ]) L2 `6 {) y if (cnt0Max[0] != cnt1Max[0]) {( X+ L- z$ m4 c1 l. X8 Q) X
return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);. S8 w% L; m* }# f [: G( H
}. f5 T& |0 F" s( I" u( e( U
return nums.length - Math.max(% U; O, ]: f" M
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
: } t* o z+ `/ a" o9 C) g cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)* D& z/ ?! U; u" S$ x5 a4 M
);
5 q9 A: d2 a h) m }
% s l/ i& \9 P( h' ^! Z8 M& |
& U& V! o! l B6 `7 z! V private int[] getMax(Map<Integer, Integer> cnt) {
: g* N% a/ Y8 { int[] res = new int[2];7 ^. c$ q+ k+ r; x" w
for (var c : cnt.keySet()) {
; w; a5 w7 g2 N2 j. G if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {0 X. v4 j( }8 G% k7 o1 Z7 d
res[1] = res[0];" Q$ A% M: X& v8 ?$ f7 \- H
res[0] = c;
: o. U4 j; }' n+ s+ P E- D } else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {, ]% {/ N1 Y7 I& e9 B- t
res[1] = c;8 F7 @- T- D0 c% i+ ]- Y: |1 E
}7 {2 l1 n* t1 n" y- b) \& Y
}, L. Z# M! }. i8 ], M; ^
return res;0 a& s, U+ S/ h/ ^+ g$ Q9 m
}& h3 b7 l, Z; B; v: H0 A
}
' O {: }& y! Q+ Q/ @& j1 x0 Z
# e( w- ?9 }: W3 x1 ^
" @) Q# I, D; o$ E8 `7 \$ i. z. r' V【 NO.3 拿出最少数目的魔法豆】
, `% k! o3 i# D4 D: z0 `9 n( t+ Z1 g
解题思路
, E! ~/ |2 Y" J# o前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
* l5 e, W$ U! I3 a# I
6 @ p/ d* @2 z! t+ j9 P代码展示. `4 k8 I2 J& T! w
7 `" y0 `* X0 P+ c1 Z/ Y, Z; _
class Solution {
2 Z, A( \0 @- e. \% l% o public long minimumRemoval(int[] beans) {
; x; p3 r/ M9 \0 B1 Q Arrays.sort(beans);
* b6 i/ j, K# S% U/ H var sum = new IntervalSum(beans);4 E- R/ m0 _. Z2 N2 z4 ]& Z- M
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;
. H$ `6 U+ d$ Z for (int i = 0; i < beans.length - 1; i++) { c) C3 h' `$ i6 C
// [0, i] -> 0; [i+1, length) -> beans[i + 1]+ U+ \- f: y6 i p. ?
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));# h) P, [: J5 g# [0 n
}
4 n1 g8 W; F' z* N( O' ~8 p return res;1 ]1 h) E+ g% _& Y! Q
}9 t8 e7 ^, h! P! ]2 `/ ~
}
5 d2 c1 ~- i4 n& g
3 p( D& z: C7 p3 Y n7 x0 R5 Bclass IntervalSum {. u$ @4 S1 {9 N2 e, N4 a% P
private final long[] pre;, G# T% c5 b4 N7 C4 @* T% |- x& n6 K
' {9 y% S; N l/ @; S$ @ q1 [ k
public IntervalSum(int[] arr) {' R) L! q% h: Q9 s
pre = new long[arr.length];
( Y: l6 K) C1 s# e3 Z% b0 R# d* ~ pre[0] = arr[0];" A! Q& b2 v, V7 K+ V
for (int i = 1; i < arr.length; i++) {0 D) [# F& W& i
pre[i] = pre[i - 1] + arr[i];
; S7 }6 p4 W9 v7 V }
' Z) j! { Y* s- @1 F0 m }
. A* B+ | o, M- [/ q# o" W" j& c) [# ]7 n0 X
// interval [0, i]$ Z) i( B% k3 s" P* t& _5 n
public long prefix(int i) {
: A5 X2 U: v; k& C) D! w3 [ return interval(0, i + 1);
- B5 x4 ~( H, S! x: m }3 _ A: b C9 d7 X* ?# s
( b" G' ~) D+ F! H6 Y! u
// == interval [i, length)
# @9 M$ z7 X! p public long suffix(int i) {) V7 O3 Z+ Z( g. o' @
return interval(i, pre.length);
- b' ?$ p2 b& z7 M0 J }- l" U& m. x- T- U4 M- T6 F
# s0 e, h# F7 ]5 r" M; y // [start, end)7 I7 c. S& h% D/ D2 [; J
public long interval(int start, int end) {% a! p& i6 O" b7 v; `
end--;7 {* t, E, O( z/ A( _/ E; [
return pre[end] - (start == 0 ? 0 : pre[start - 1]);7 l! w! \" g7 j
}/ V* C( K1 r: [# q( Y _
}
2 `* ?7 t5 o' X& q- Z- f+ d3 ~$ M$ n. E( Z U3 L" q- J* M/ j9 @
: U# K; U$ `& m' Z' \0 R3 R! ^
【 NO.4 数组的最大与和】
/ C* m0 s% `0 [. ~2 a/ j) X1 E/ K% `( o" A# R
解题思路
5 Q# T: M' R) x记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和
' `2 i/ O2 _, c7 N& a1 F3 U9 M* R+ h& ?2 T
状态转移:枚举当前数字放到哪个 slot 里面
! f+ z/ ], H% Z
* X4 y! O3 c( O. l2 B5 ^答案:f[0]
2 B0 R; r2 ]+ G5 u# c; y! M
7 {1 |) l7 c% _* g/ i0 b: J其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字8 o: m' G: v$ G, [, v8 v
# V' H5 k# |. _0 R4 T代码展示4 S* |: @$ h9 f2 ^$ t
$ K) x3 I# t- |4 qclass Solution {
. K/ s" @$ L/ _/ Q! t! A public int maximumANDSum(int[] nums, int numSlots) {
( s7 [1 j$ C6 | L8 C8 l
4 D$ T) ~) s3 c8 T$ n5 C# X) \ Map<Integer, Integer> mem = new HashMap<>();
; ?$ ], ` w5 R' O' z' {0 l return maximumANDSum(0, nums, numSlots, nums.length, mem);, [/ ]' M% k7 q& j
}4 ~# w* r9 P" s
! [$ [5 x$ @8 z: H7 G private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
6 x/ C3 g( o$ ~' u1 h0 {4 j4 J if (mem.containsKey(stat)) {# w' _" B9 {7 N7 T
return mem.get(stat);
/ K, @, ^5 w4 ]3 T8 q% @ N }
8 s% |8 a3 b3 B0 w3 y c+ Q' ~ if (numLeft == 0) {$ M8 x% s% x5 V( N
return 0;
6 S j2 h2 k% x! `& d, F1 t+ x8 R( q }
6 N3 Z C/ x6 P* o6 }( G' n2 Z. O$ c3 L% |2 c! X- o
int curRes = 0;0 ~) u) J+ J+ g! X; G
for (int i = 1; i <= numSlots; i++) {$ U2 O; t2 x* Y" z& Y
int slot = getSlot(stat, i);! D. R i5 }( u0 B3 z; O
if (slot == 2) {4 ?4 X1 k/ Y/ v/ q6 r, F$ ]
continue;
- O: I4 A D- t; c/ z5 F" R }
& c' d2 e; {6 a) d/ S: P int and = i & nums[numLeft - 1];
0 d6 q8 a5 @9 l; L! b int stat2 = setSlot(stat, i, slot + 1);6 Q O$ T% R _. J/ i9 I3 C# V2 N
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
# k! @( b% M( d/ U }
" s( c2 d( l/ Q' f/ Z! q
3 ?1 \& }3 j) l( x) v mem.put(stat, curRes);
( u. O6 q7 Q5 C0 Z# r, Z7 w$ K return curRes;2 R7 ^( k9 L6 ^# S
}
+ J2 E* A! ]; M6 r' H/ j/ M9 U
, x, j% y- w4 u: U; O( q; g: }$ f# V // i start from 1
' L. ]4 W! p* G; n2 @ R, T private int getSlot(int bits, int i) {
5 a' x: \8 f! `& `) B( P( D8 { int offset = (i - 1) * 2;
# A! C9 R$ y9 t' \ return (bits >> offset) & 0b11;
9 r/ p& o4 @, F# r }
6 ? U7 P* t9 C: T$ o8 V" H o2 ^. K8 {, E, q( y) t
// num = 0 or 1 or 2
# Z0 t; x$ O* p+ i private int setSlot(int bits, int i, int num) {& D: V4 }6 `3 v/ H4 }, K+ m6 R+ U
int offset = (i - 1) * 2;
f' Q( Q% k, K4 _( {6 g* M bits -= bits & (0b11 << offset);: U" S/ H6 l p$ U& L* q
bits += num << offset;
1 Y. F% d( m4 V return bits;
4 ^4 U' T7 O. e6 o/ v3 K! k* U9 O }3 z# J. H# I$ y
} |