登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】
: w5 y+ R" n6 M* R
! g# L" Q, e" q7 L解题思路
( Z: g M' }; l) m- T签到题,模拟操作即可。7 E+ P) G! P* W/ e: z8 c7 F6 O
& @- {- `8 n5 A, B: Y( g, T3 y
代码展示. [+ I1 b- u$ q6 S& Z
, j6 N9 q Z$ f- K( G* O3 g
class Solution {. Q9 J: K. p. t( x
public int countOperations(int num1, int num2) {
$ R5 z* f4 T7 J( C int res = 0;
' \; w/ x( P K# p" i/ J. r8 ` for (; num1 * num2 != 0; res++) {
; i8 V! m2 }) n& b; a& W: l: @: m if (num1 > num2) { T4 n9 z: k# Y" _4 J3 K: z
num1 -= num2;4 t; h9 t! N6 x' n3 r, Y
} else {) M5 a4 I* P+ T; K. W- p
num2 -= num1;
1 g7 D- I/ z; J8 |, z }6 s* R6 I a- I: Q5 I S
}
/ ~0 c" z7 V; J# z+ e; E% g, t+ g return res;1 |4 x, l# T. J( K# A6 p3 I: ^
}3 K2 z! t1 X" P( S
}
4 g7 E6 P0 G. G1 l! u. l, S0 o! ]1 j4 K" ^5 ^5 p
9 C6 H: O% y' _
【 NO.2 使数组变成交替数组的最少操作数】
, F. e/ C; i% F% u) T7 g2 [. P2 ^. P
% g T& {, c4 U* Z8 G解题思路. C4 R h- c6 _8 p5 v7 s" f
统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
. Q! Z/ `! P! {+ v: u: n( e- E1 d% g7 Q+ i! N
代码展示
5 Z! V0 ]) q- |! _- ^ m8 N" o& X
3 ^( F! U0 s6 N6 s. D* ~class Solution {3 ~$ y" k2 ~& @1 J' y8 K) W @
public int minimumOperations(int[] nums) {- A- S: o# Z, r+ @, ^
Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数
, _9 }; F' a' @ Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数" u! q- W: E" @5 b! n: P
for (int i = 0; i < nums.length; i++) {
U/ Q0 H M9 r if (i % 2 == 0) {
* y5 {: f8 L8 g' O5 k& R9 g: P cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);% |- x1 p/ K# D+ ~
} else { D G% g" O& W3 v. m9 K) y9 W
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);
4 U; p* b, H7 X$ Z& b; ]9 T& Y& G }- r; A' s* {- Z* H5 J: C& X3 c
}
0 ^& _5 t( r4 l int[] cnt0Max = getMax(cnt0);
1 B s, z' g" v$ P$ P int[] cnt1Max = getMax(cnt1);' ^7 g2 d0 P: g& [2 T
if (cnt0Max[0] != cnt1Max[0]) {3 N* m2 c0 W3 l# B! ~; I5 b
return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);3 r4 ~- h" z6 s% W1 }) r1 c9 U3 b
}2 o" S c* X1 F/ B' R# p1 q
return nums.length - Math.max($ W% q4 W0 i1 ^. V3 [6 G4 [
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),( n$ S3 J$ Y9 v* a
cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)
4 G0 j) U' S1 l m. P( v5 t );2 _) a# e# m+ \- P! W# r( |, T
}8 h+ o+ k# V6 M3 n: j( O+ W9 |6 w
& ^' r9 U$ M3 e7 n
private int[] getMax(Map<Integer, Integer> cnt) {
3 A5 \" A# F/ P3 T9 Q( t/ Y int[] res = new int[2];6 C# i2 D4 |: ~ Y5 }2 x$ R
for (var c : cnt.keySet()) {, a8 I5 s, f; ?9 ?, c. o
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {( K6 n1 ]- C/ S% R
res[1] = res[0];
7 n; N% |0 V' G$ Z6 Z res[0] = c;+ H* w- m: B8 W1 }2 S
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {$ j1 O b0 B' _+ e$ v
res[1] = c;
4 i& m( D; v% C }
! ?0 r7 |+ Y; D) ^7 {4 O2 C; K }& l1 H- a }# X! \# ]% M" ~2 S/ K
return res;
# n. c- X7 w: W; s) m9 f }
4 Q9 m# S) s% W}
% k* p. h4 _: ~% ?, v- E& j: p, P$ w' ~1 R
4 `6 y$ C- p6 A8 Q7 A, k2 ~【 NO.3 拿出最少数目的魔法豆】
6 n/ W; N0 U& z; [# \
6 b" C9 {% j# H2 O4 k% \解题思路* r9 W+ R2 |+ F8 P) t
前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
( F9 v6 d3 N7 `. I6 B/ {0 a: u/ I) J0 z
代码展示
# R) h. T8 q+ x* F/ s+ c/ B: j$ `1 `- a5 I
class Solution {: E5 D2 w5 C5 v+ b0 s
public long minimumRemoval(int[] beans) {6 `7 ]' j4 A+ n! `9 D
Arrays.sort(beans);
( z" `. T) \( @ var sum = new IntervalSum(beans);6 g0 B- I5 T- o7 [: f) W0 ~6 X
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;
2 V" \6 o6 V+ N3 t5 q for (int i = 0; i < beans.length - 1; i++) {) T+ i/ r, \( n! J0 s9 U/ ]
// [0, i] -> 0; [i+1, length) -> beans[i + 1]
! H* G' P4 J. B' W- S res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));& i& b& j, O' S t7 y
}9 Z8 s7 G. z+ H1 P" b
return res;
7 I: ` B& V1 u' Z' Z; r7 p0 v }9 ?" B9 ?2 k: c0 i* m
}8 I' a- z! ~' v- w# v
8 i- }) W- \0 j" {# t/ I: Z: X
class IntervalSum {; a! B- b3 e9 R1 K D
private final long[] pre;$ |' P4 G, c2 k" X0 C x9 ~$ d7 m& z
( b& V4 d! v! v& l# T public IntervalSum(int[] arr) {
. @+ M" U: w1 R4 M" D* m/ [ pre = new long[arr.length];# ?% v# Z$ _! W4 _ Q
pre[0] = arr[0];
- i7 O5 ]: i) J. f0 A for (int i = 1; i < arr.length; i++) {
9 H* v8 {5 M0 k$ I. s; P pre[i] = pre[i - 1] + arr[i];) T) m. Q* ]( G ~! Y1 a
}
" F- W$ n$ s, {) H) n6 }8 r' p }
# d0 Z8 M* D3 x- g6 N
: t7 t. V; @2 x8 _$ r) J0 _ // interval [0, i]8 o$ h- S: `: G4 `, B
public long prefix(int i) {
3 m0 H' o+ j* i. y4 V! l return interval(0, i + 1);
& a5 Z+ f# ]5 s1 C4 G0 L7 T1 ] }, P/ X$ T, `: A2 a4 \
+ c$ X; I& q6 }' J$ h // == interval [i, length)
6 R5 A9 E) _- Z9 p1 l public long suffix(int i) {
9 H7 e& k7 K5 e+ Q+ t' D! E6 E( z return interval(i, pre.length);# G# L0 g- P3 |
}
# O9 P9 x# V. s7 u) m+ M* k4 N$ C3 s7 D# u" | w( z* z
// [start, end)2 ]' K* Z5 B' K0 o3 f G; |1 V! Y
public long interval(int start, int end) {
4 ?% g; J* j2 J& `1 q$ _ end--;
& d% h! Y* R- }2 m9 [ return pre[end] - (start == 0 ? 0 : pre[start - 1]);
$ u2 _ s! X! T }
& W1 c% b! X9 C1 ~$ j0 T}
) N+ C# c: {* f3 O
( M1 n6 Q" C) y5 o- e8 l- D% g* |7 X2 s6 I9 E
【 NO.4 数组的最大与和】6 u& v, ~- @. X$ \
0 B- I% T$ D! t, V6 ^; w
解题思路
$ j; g" {3 F+ P& m, C8 y6 Q2 v! \记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和
+ W5 @' N+ |9 N. D. _9 r$ h( H) j. k& a. k0 s4 t, P$ C
状态转移:枚举当前数字放到哪个 slot 里面
& Q4 w: |0 u: @9 e! M/ |9 \: o4 i2 K" u d, j) P, f
答案:f[0]
. M& I; e, C! |2 K0 L, |5 C; d/ E/ x2 [' i. ?) m
其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
) Y1 [. D$ _" [$ G! G( _# ]; Y! K2 P4 P1 d# y9 e4 P0 t8 f
代码展示" Y' Y0 h0 I# z# W2 N- ?
( A* Q5 u4 G& `1 n. m. A" F' _
class Solution {6 }5 u H8 ]! R. k
public int maximumANDSum(int[] nums, int numSlots) {: v0 B( p$ Q8 E2 H
1 X3 c& F9 j7 A& @5 {* s6 O) r% d2 Y Map<Integer, Integer> mem = new HashMap<>();# L7 v- i) n$ n6 t% n3 {
return maximumANDSum(0, nums, numSlots, nums.length, mem);6 {( t; v: _5 [3 M7 k
}
+ o$ R) q8 _& `, ^
( D# [. R2 G2 _) R, W; S private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
# D* J4 F0 n( Y$ l- c+ N" ? if (mem.containsKey(stat)) {) f: d# x' E. H3 J
return mem.get(stat);
$ s0 h% H5 Y1 K5 E& }4 L }: Y& V" Z' _4 e! q7 V" B/ V4 o
if (numLeft == 0) {. C2 t) Y; \- R2 S
return 0;
; @, o, ?8 N5 i B2 H$ l9 v }
- R$ H3 b) ?8 G" D& f# a4 L
9 m! m j% z2 h; ]0 i4 A6 Z7 C* } int curRes = 0;1 U4 D; }! u8 p; a G
for (int i = 1; i <= numSlots; i++) {
& u4 @& k! o' s0 K$ F7 Z int slot = getSlot(stat, i);
3 p- E" ~9 F; a6 e2 u& |, X if (slot == 2) {
% s" T! t$ {' \+ t- c+ l continue;
3 @6 ^+ s# \$ H }
; d7 t; a2 Q! B; Q9 b2 H, {* g2 e int and = i & nums[numLeft - 1];
" z! K: {6 ?' T; M% K$ m3 |- Z5 ^ int stat2 = setSlot(stat, i, slot + 1);
! N5 v P5 w+ D' H9 |# G curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));
1 e7 w; Z5 L0 E: s' ? }
6 S T1 G' {6 A; ^9 P. k
' w! J. K& |" x. S& C) G" H mem.put(stat, curRes);) P6 M% R# \' ] I4 v5 q" i
return curRes;" F$ Z8 q9 G4 f9 F! [
}) u1 W! t$ t* R" @1 L
4 I2 R7 i# U% ?! q // i start from 14 c( ?( B7 e6 u6 Y& Z: Y: X0 ^
private int getSlot(int bits, int i) {- h* N. m; R% s+ H
int offset = (i - 1) * 2;5 w+ {) N9 Z5 q2 {% l; S" W
return (bits >> offset) & 0b11;" u- w( o/ X' ?4 q/ h& ~# W( Z
}. o, Z5 @- c0 v# I- f# R e
9 F# k5 j9 s/ y$ b# L2 }. C* T9 j( I
// num = 0 or 1 or 2
6 Q; q( g" z) K$ r+ P9 I9 d8 _ private int setSlot(int bits, int i, int num) {
3 _0 c# x- ^1 |0 V& B int offset = (i - 1) * 2;
5 h1 R* h# M0 x$ L R" r/ j bits -= bits & (0b11 << offset);
9 O1 r8 B {" `% }" v7 a: y bits += num << offset;
2 z7 E) } O, t8 S0 } return bits;
4 ^3 S' Z2 U2 h" g x" F9 ^, Q }
2 ?5 o6 N. `6 E$ ]} |