登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】
7 B1 U9 V/ o; I( p, F7 g# E
' m, w' p1 W# U2 j% i解题思路0 h. {% k0 W8 @- G" o1 V' e3 ?5 [
签到题,模拟操作即可。5 U9 y0 ^. c% ]
( @$ G0 }5 I" X8 J* }! L
代码展示
" j3 |$ R6 m8 j: R* B9 o2 q2 @) ~
2 p9 l9 G3 a8 z& m; Q) r( T. uclass Solution {7 a7 j# s. N1 l8 @. o: z
public int countOperations(int num1, int num2) {
0 l! }: Q% U e7 [" r6 w, P! m int res = 0;
3 o" l+ S" o) M: L7 p for (; num1 * num2 != 0; res++) {
; H& n @) \' o( p i1 | if (num1 > num2) {
! ]4 i+ T# R+ M: W2 b7 [ num1 -= num2;0 c$ l( K6 o. d V
} else {% @8 j# t' _5 L" R/ n
num2 -= num1;
* j! K8 j; N! C! c; b }( w1 N/ i- T7 d
}7 l+ W$ H" G$ e! X9 T
return res;9 D9 d* v1 @9 _: h; d
}
4 t+ k- j- C& A v, Z}, x5 d! ]. \8 S# x
8 M, W) K& X- v4 p/ F+ s9 ^; q
* e; v7 o \4 U- }" ~1 ^
【 NO.2 使数组变成交替数组的最少操作数】
1 v; V. d1 L' S; F7 M9 d4 Y( L4 n. F$ Z- s0 O( f
解题思路 X% ~3 L, w7 D7 `+ f, t4 t
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。. D7 O8 b5 T0 ~' S2 ?
- t( k( } J9 q% n; ^
代码展示5 Q( j) J; ?* A: B
" y# t( W$ t$ _: s. ]class Solution { \6 c/ T2 P+ b5 M
public int minimumOperations(int[] nums) {
" s; f1 g5 z+ O% ]& g Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数( ] [2 q' a+ U8 M
Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数; V: H& J% q( p/ E- g, z1 \* q
for (int i = 0; i < nums.length; i++) {/ f% o$ X% d/ P% e& J9 c
if (i % 2 == 0) {
( A0 Q! F/ N5 c. B$ K cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);+ E7 T4 y+ e% }- ]* m# @) x% w
} else {
- O# }; s P& i& D& M4 g7 s# e cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);
8 {1 q% u0 u0 E/ a! Z }
& \8 C7 m. R: @: u9 ]1 n* w }
1 a) U1 r, x9 S$ V; M' R int[] cnt0Max = getMax(cnt0);2 \( b& _/ V! w3 {# A
int[] cnt1Max = getMax(cnt1);/ a7 N; ?4 U+ Y: s! U8 c1 T. A1 E
if (cnt0Max[0] != cnt1Max[0]) {
. s' R& t. E0 S+ W+ X. v/ Q return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);( c; O! \1 ]3 c; C M+ s* Q
}
$ m; V g y" U$ J return nums.length - Math.max(2 M% Z6 E. q( ^2 T' P9 W# y
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),; H' l( S* ~' n1 \* o0 m/ y6 q
cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)
# u8 v, ~6 x$ ~, i- ~ );. _$ j0 [3 L* @7 f- Q7 _& u" t; E0 l4 G
}
7 s/ `& p& G, f+ S7 E# ?3 K9 A N- H- s1 Z
private int[] getMax(Map<Integer, Integer> cnt) {2 H3 v) D7 }/ b* p" v
int[] res = new int[2];+ [4 N; G) n* @% l" \: ]3 @
for (var c : cnt.keySet()) {/ W2 g7 m* ?5 P9 u+ c# ^
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {# D# c6 Y; _( t8 U( u# c, Q- l
res[1] = res[0];
% c8 @* `& w& q/ A0 O+ P. ^# W) T res[0] = c;
6 H) c$ [% m. u9 ^ } else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {6 r9 e4 s9 r7 H6 Q G# I
res[1] = c;
2 A* M& k# C" @; M) |( ? }5 W. ]/ l* P+ ~: f' N8 W
}
9 a! k# o% q g. D return res;
2 f; c5 K X9 n }
! z, T2 o) X# w2 R# A* g$ O}/ E2 X M6 h, ?( c
% K! h6 v. F0 ^% K- L5 t
_9 H$ z3 L1 l4 f1 w
【 NO.3 拿出最少数目的魔法豆】 o( O: k: o q* J3 \
: w% X- s% d0 V1 f7 S0 h解题思路- c, S2 s; o. g5 S0 B4 q1 B% t" j
前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
- f- q6 h p; x
, }! q1 B) j, Y3 ~# g6 j' Y' j代码展示
" ]7 Y! e$ @( H' m( S% h2 K$ }* a: d% R; [8 T8 s
class Solution {
& x4 P7 s; c3 R" a public long minimumRemoval(int[] beans) {
& y( M/ c0 E% \$ h u! O& ]4 F Arrays.sort(beans);6 d6 d( _+ F9 K/ I+ Q4 {1 o. [7 o5 t
var sum = new IntervalSum(beans);7 q# y+ B6 v) K6 p
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;2 E" y' i7 u! ?" D' R- l6 e7 t
for (int i = 0; i < beans.length - 1; i++) {) ^6 I: A) T0 ~( W1 x% m6 s7 A
// [0, i] -> 0; [i+1, length) -> beans[i + 1], {7 ]* z7 j+ M8 e9 @# B3 X; I2 }
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));
- @& t/ _3 Y8 u& C4 Z u& U. D }& m2 q g! X+ c+ `) Q
return res;
8 h# `, W3 n& L/ R }& s; c* L* r$ S7 c n4 i, T3 A4 ?3 K
}- [, @* }- L" l, ^3 R; a' {& U
* T5 M7 r' z; d
class IntervalSum {. D) K% E8 Z3 d" c
private final long[] pre;; V2 } e: F) b3 f. N
/ O8 ~) L) v; J. B L8 j
public IntervalSum(int[] arr) {
# f- p6 F2 ` H pre = new long[arr.length];' X- O+ Z: x5 A- ^
pre[0] = arr[0];
5 v; D/ o7 A" k" ~6 C6 T2 m% L N: \" _$ t for (int i = 1; i < arr.length; i++) {
+ k% {& m# x! m4 W1 L$ F pre[i] = pre[i - 1] + arr[i];' J( J; B) E0 e3 R
}
% ?0 f! l( |* k7 }! M }+ B' z5 g6 a# u: a
% |3 C) }: x1 I7 i0 c) f8 t E. A // interval [0, i]
: w8 y( l! @3 _ public long prefix(int i) {
+ M' A2 A% X) c$ ~- G return interval(0, i + 1);
3 n3 ~1 E i# X( b, \; S }5 W* ?2 t3 z/ m5 Q1 d N% O! K6 w0 P
) l/ t2 o% l! B6 [3 w! p. ~9 I
// == interval [i, length)
4 x/ C9 l- n4 j- ~ public long suffix(int i) {
9 n5 t D; Z5 p/ S) h# [ return interval(i, pre.length);
9 [4 \: t9 f) R3 m, M ^" m+ i }
# i* J2 P' L* C2 ^
" d. V6 ^. a0 a1 _! i% H- x; ?: G // [start, end)
! ^. h+ {1 t& _8 r# a public long interval(int start, int end) {
. p: }/ a4 X2 m ?. M end--;& G: K- l# t- M' E' R
return pre[end] - (start == 0 ? 0 : pre[start - 1]);, H2 p) C2 x# R, ^
}
% V7 i; \) i v1 L}
6 B* ]; w8 o5 t" m
5 u3 r# a) K g/ M( N% e& r# L6 T5 W7 k! o$ K
【 NO.4 数组的最大与和】
4 ^; d2 S( K P ~5 k8 c
' K0 h2 `9 G/ t0 W8 ]# p解题思路
3 v9 p: l$ W& Z; p记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和. R# L& P# _/ ^" Q
* A2 V3 ?! T9 v, n5 u8 K7 [' H状态转移:枚举当前数字放到哪个 slot 里面
3 S/ v1 n# V0 Y" R6 K3 V1 c7 Z& [* D: E) \1 ^7 A+ Z
答案:f[0]6 D0 ?2 P+ y6 f# @7 x6 o* H5 x( C
) L( C3 i+ u( O* Z7 E其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
7 `# T% Z7 {# D5 y; _, g9 b- U% m5 u# z- _
代码展示
. ]- r6 X! w) [' V. }3 m6 d
; o' m. W3 G- m& S( p1 ]0 @class Solution {8 ]$ l4 S+ u$ ^3 J, {% u
public int maximumANDSum(int[] nums, int numSlots) {
8 W$ L9 B# [8 D8 `) _5 o5 h" A% n9 \5 a. w; V6 w- Q* l1 `3 B5 `# C
Map<Integer, Integer> mem = new HashMap<>();
8 L" O$ N8 k7 _ return maximumANDSum(0, nums, numSlots, nums.length, mem);4 m T& w+ L7 S0 V$ u# U
}
' C' R4 A7 e% L, D6 V1 o( |8 _% l% M$ N
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {2 @1 B3 V5 y" R. v) T2 K
if (mem.containsKey(stat)) {. Y U0 N0 V4 `$ h$ J+ x
return mem.get(stat);
: r N- `* d% A( ^& f }
* a) H, }% @* c# e6 I- i if (numLeft == 0) {
$ b2 N. y U) _& z return 0;8 |1 g2 P( z. b" x7 F
}
" B+ u" e, N& Y8 Q/ W7 K; S9 R2 S
# v9 w @- S4 \( z int curRes = 0;3 n) s7 s; M( ~5 y
for (int i = 1; i <= numSlots; i++) {
, K, Q+ {4 t3 q* l. m$ k, T- a int slot = getSlot(stat, i);7 F1 k1 ^4 K+ S& u4 |
if (slot == 2) {
( A) L+ C# y1 u0 j% y. e continue;
2 a; L1 |# [* j% o' p) `1 x }/ i" Y1 Y" V! s( ?* w
int and = i & nums[numLeft - 1];
6 [8 A' n; A" L0 v( V- H7 q. ^9 I int stat2 = setSlot(stat, i, slot + 1);
4 ?6 L# N+ Z8 ~' v curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
2 s( d0 C% A( R2 [/ K }
- G. g: G+ r* I4 A: h! k, M2 `0 [8 {& ?
mem.put(stat, curRes);* f2 N9 b2 X7 P4 `, {; h
return curRes;7 b+ T$ l1 Q% q& V) |
}* @# c+ k5 q* {
9 ~6 m( }$ s7 J! H( O( a
// i start from 12 {. M) x) M9 S$ h4 F5 {7 a% F
private int getSlot(int bits, int i) {+ T; y; {0 `8 U9 o4 Q n
int offset = (i - 1) * 2;
3 f' Z7 {( Y' ]) {! M return (bits >> offset) & 0b11;5 T/ y# H0 R4 _' S4 T& P5 c9 v
}, n/ L9 ^. s4 E) c, E. b. H
$ v- C# \; C9 q8 A. ^& ]7 e
// num = 0 or 1 or 2! a$ n( a' f" |
private int setSlot(int bits, int i, int num) {! T0 v/ ^" F. w c% w9 E
int offset = (i - 1) * 2;* Y9 W5 @. F6 I: Q3 B+ i! j) L7 O s
bits -= bits & (0b11 << offset);7 E% _" D; g* e) L9 \& Q
bits += num << offset;
! {6 N2 O9 @) X return bits;
5 F0 G! \5 Q$ u4 c) _ }( k& {$ S k Z1 J' j
} |