登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 得到 0 的操作数】
& K; M$ n K+ @, y+ p2 |( p) y% J+ M6 X. w, E9 _& |+ L. j
解题思路0 V; a( N) L. J4 B- j9 h0 |
签到题,模拟操作即可。
" }2 n$ m* ^& U* ?/ \: @/ A D0 v& P1 m+ M! v2 k
代码展示4 z: d. A5 @9 ]/ \
! O3 H, p+ W7 Q7 Hclass Solution {
) I( G1 a3 X' `/ f public int countOperations(int num1, int num2) {4 B6 v5 }+ Q- J& [- ~
int res = 0;
) L% }: Q3 \4 H6 l$ z8 q for (; num1 * num2 != 0; res++) {2 Z5 m9 E/ u1 ~
if (num1 > num2) {
0 z0 C+ w7 u( p num1 -= num2;
7 S6 `4 x0 ?+ ~1 O) X% u } else {
* q9 c! X1 m2 g4 D1 W( T num2 -= num1;
$ ~6 B6 d7 D( E a1 T }
6 \6 K( _& B- b }8 t3 m" @% G! i+ ^& Q* q
return res;
5 J6 |" I3 a" t) v0 ] }9 b( i2 h. x7 X1 A! Q
}
6 U( P* g6 @* |/ b& |( a! d/ `4 M3 f! Q1 M, z/ ~
# P8 N2 Q9 q+ R \* s5 d【 NO.2 使数组变成交替数组的最少操作数】& F7 T- Q! g9 x b( z
7 Q8 P. U8 h$ s3 k4 s+ Y) s. f解题思路
9 @ B- D7 e5 N$ W- t S; h统计每种数字在奇数、偶数下标上的数量,然后使用最多的和次多的作为最终数字即可。
) |9 d! j0 b6 J! e* y
+ a. A) G+ f* u( G1 I$ ?( R' c代码展示
; ?2 E4 e/ O! H% O1 L: @1 X" o/ q
class Solution {
! S4 y5 X# b i; m public int minimumOperations(int[] nums) {
. |1 p4 \8 v$ b5 s# L+ g/ C: A6 e Map<Integer, Integer> cnt0 = new HashMap<>(); // 偶数下标计数( f- o% |, N: k a# U) m0 g
Map<Integer, Integer> cnt1 = new HashMap<>(); // 奇数下标计数% [% V1 N) e: [
for (int i = 0; i < nums.length; i++) {# w% T# M1 H: @3 Z
if (i % 2 == 0) {" f8 s9 j6 @: \& s( a% d* d6 }
cnt0.put(nums[i], cnt0.getOrDefault(nums[i], 0) + 1);
5 Q8 u3 Q0 Z% |% k! p } else {4 Y8 E4 e' n% Y2 f+ K1 v2 m
cnt1.put(nums[i], cnt1.getOrDefault(nums[i], 0) + 1);$ {# y! D/ b5 z6 ]3 X1 Z# a$ ^6 |
}, A8 Y/ G6 H" W
}- V7 w! L2 D8 ~9 v. S; s
int[] cnt0Max = getMax(cnt0);( [* ]# y8 T! y; f8 S$ f
int[] cnt1Max = getMax(cnt1);
B" B' M$ H2 ~5 I6 F: P" t if (cnt0Max[0] != cnt1Max[0]) {
" H& J" w8 x. O) h+ I- Y! D# N return nums.length - cnt0.getOrDefault(cnt0Max[0], 0) - cnt1.getOrDefault(cnt1Max[0], 0);
+ }* i+ t2 G ^- e% r' c- u# k }, h* {7 B+ K$ [
return nums.length - Math.max(9 P4 V) F$ `' P: Q! V
cnt0.getOrDefault(cnt0Max[0], 0) + cnt1.getOrDefault(cnt1Max[1], 0),
- N H# e! L9 S cnt0.getOrDefault(cnt0Max[1], 0) + cnt1.getOrDefault(cnt1Max[0], 0)0 h3 K9 e% _' T+ d v3 K; q. K5 ~+ C2 _
);# N- `5 Q4 S$ v' j) k. {
}. I- k b4 @4 w/ Z
7 L% U# a& {0 j! [. t- ^' [
private int[] getMax(Map<Integer, Integer> cnt) {+ X) |# \/ H$ r6 F
int[] res = new int[2];2 R B; q! D" o* F+ o" I
for (var c : cnt.keySet()) {3 R( f' _; ~/ ^, h/ A
if (cnt.getOrDefault(res[0], 0) <= cnt.get(c)) {
& I3 X3 U% Y4 P; P8 b0 V8 |& R res[1] = res[0];/ {7 E. q3 x+ E- |' m
res[0] = c;0 Y9 n& Q. X) X" B
} else if (cnt.getOrDefault(res[1], 0) <= cnt.get(c)) {
# A2 y! N8 j: S$ j% o! I) t7 O. _7 h res[1] = c;( k0 ]% H5 @$ H% ^- `: ]6 N
}: t* Y5 E6 g; H2 b% [/ H* ]
}% E3 P/ I4 ^" Z1 v4 j/ Z
return res;
* d, U0 v. s0 `9 R0 b' L) R- w } x: q4 h/ M9 }- U
}9 m8 T5 P5 _( z- T
3 t: \: u$ T8 \1 ^
9 H; Y% b8 b# g# Q% e
【 NO.3 拿出最少数目的魔法豆】/ u; e: E8 t( s1 h/ ~' B+ d, H* j
' a+ p7 l4 w$ E- X
解题思路
6 E% g8 |- T( f' v* S; H0 u前缀和。排序后,枚举分界点,分界点之前的全部置零,分界点之后的全部置为与分界点处相同的数目,通过前缀和可以快速计算。
7 w& o) F8 J- g
: A+ Z R9 \: v( U: ~: g代码展示
( l9 n9 z" p# w$ a! \$ t
8 j/ K. A, O/ i* `class Solution {
+ E& d! ^" N: j1 p public long minimumRemoval(int[] beans) {
" h6 ?9 e$ u+ y+ B0 l Arrays.sort(beans);
2 q+ {$ m" P' m var sum = new IntervalSum(beans);' @6 E3 T8 K9 H' }4 T! T7 f
long res = sum.suffix(0) - (long) beans[0] * (long) beans.length;, i! d/ G' ~$ B' g- t H
for (int i = 0; i < beans.length - 1; i++) {
3 v# _: V3 A* p$ g. z! @ // [0, i] -> 0; [i+1, length) -> beans[i + 1]- P( z' X$ l$ C" f; Q3 U2 |, R
res = Math.min(res, sum.prefix(i) + sum.suffix(i + 1) - (long) beans[i + 1] * (beans.length - i - 1));9 o' Q# \( o( E, x. A* R
}
. H4 [4 z4 _5 v: ` return res; X# V# o+ N, X8 ]6 U* V9 t" `
}
7 t' L5 G, y9 D9 b! i t( v. N' s: T}! ?& }& V* l6 U) u+ X! @
3 A. ^0 t% i8 O4 ]5 f4 G
class IntervalSum {5 }" c9 m% t6 e# @* E/ J6 F
private final long[] pre;
k# \$ Z3 g G( N$ B$ q, `9 ?7 N9 y" Q. ]
public IntervalSum(int[] arr) {
7 T$ U @* E* R; n4 B; g* r4 w5 O- v pre = new long[arr.length];
7 ^* {! z& Z) P8 H( v; e/ S% Z pre[0] = arr[0];
7 K, p8 Q! P, n2 s% A, @2 n for (int i = 1; i < arr.length; i++) {
0 z/ W! Q0 Q+ o. \' Y) y+ [ pre[i] = pre[i - 1] + arr[i];
5 W6 R* V# j! v" u9 g; n+ | }
% M1 R2 ^; x9 [/ D8 @5 T: p9 v! ? }
6 h! C6 ^# O" h! |* L
7 j0 I H2 B+ a: }9 W4 c // interval [0, i]
' j8 p; X0 d5 V( t3 h+ R public long prefix(int i) {
' G' u) {' A+ Y; t0 u" r: G return interval(0, i + 1);0 A/ L$ r1 i( \7 s7 |* Z7 z0 a
}
6 r$ L& Y2 p1 X8 ? J
# X6 X$ R5 r2 E' @3 X0 } // == interval [i, length)
4 w, q! R6 m/ d9 k public long suffix(int i) {
& V/ l- A' m: [* W! Z. h* O0 c return interval(i, pre.length);# _* I+ S7 m/ c0 O+ U* ?; p N
}
# t/ G0 W6 n# m
3 D# B( {7 Z$ s% | // [start, end)7 D$ F! t. q4 w
public long interval(int start, int end) {4 D9 q7 i, X2 R3 v- _) O6 e
end--;
r' ?. p+ _" R! r; I return pre[end] - (start == 0 ? 0 : pre[start - 1]);
5 }9 \+ |- Y9 X# D- N0 N" J {8 S }
) ] G" B" T- [. b}
' k: g+ g6 {. K* |0 _
6 X8 W) W8 ^. S/ i1 c7 h9 e
) {: e) P' Y- @1 X& C5 h9 o【 NO.4 数组的最大与和】: R3 U* _2 f7 Q0 P C5 e+ z
9 n' I! y8 [0 r- e- R, @8 W, L! r/ S+ \解题思路( Z8 H9 Z2 |" B0 D1 o# p
记忆化搜索,令 f[i] 表示 slots 状态为 i 时,还能获取到多少加和' v/ P( {2 G- g. r0 L# Z
0 X+ X A, Y9 |2 u状态转移:枚举当前数字放到哪个 slot 里面
! c, U! I5 v5 B: Y. a+ A
- y* H; N$ [1 }/ c4 u. V7 K. O答案:f[0]6 s9 t% ~* p* s' u' S) _% p9 b8 T
: e: G& N, v: K* x! b# f2 }
其中 i 是一个 18 位的二进制数,每两位表示一个 slot 里已经放入了多少个数字
/ c. u% v( r# V* t- f. j+ f7 O* f8 b3 b& q3 _: O
代码展示
$ V" R/ I& [; p" c9 g9 C- a- l) e) d, z* O: k
class Solution {
. P. a0 z5 L% b; \) a* w( y+ | public int maximumANDSum(int[] nums, int numSlots) {, j$ |# N" d: F7 `+ I- ?
3 K9 P9 `2 Q- L6 s6 v
Map<Integer, Integer> mem = new HashMap<>();
( o& U& ^" E, P2 r1 r* |. O return maximumANDSum(0, nums, numSlots, nums.length, mem);+ K' W" a, U8 I0 ~
}' v/ \* k( ? n. |6 Y+ W
$ C; _7 P6 j7 u. a
private int maximumANDSum(int stat, int[] nums, int numSlots, int numLeft, Map<Integer, Integer> mem) {
t/ B0 l. j6 `! T5 l: T, H, D if (mem.containsKey(stat)) {
+ ?7 b7 C$ y& n6 G return mem.get(stat);
5 s: [2 u. R# E }1 k) K, y* i$ d
if (numLeft == 0) {3 {3 r. ^$ s. z U3 _
return 0;1 y1 j/ U( I( S6 f$ e8 [
}
4 I- v N; V) {: ^ g7 R8 p' ~! k+ j- X5 w( K
int curRes = 0;% H! ?+ ?' {# ]8 c3 J
for (int i = 1; i <= numSlots; i++) {6 H' c# o+ V% K8 I# l% M; m2 I
int slot = getSlot(stat, i);' G% l/ j- [- ]
if (slot == 2) {7 R q4 I9 ]8 W
continue;8 P( ~9 U2 x I( v. j# j8 q5 i
}
0 g7 Q4 O, Q; \; f7 E, ]4 m& s1 C a int and = i & nums[numLeft - 1];
4 i$ p! ]2 v% w1 ~$ E int stat2 = setSlot(stat, i, slot + 1);9 Z, X' I% W) R- [
curRes = Math.max(curRes, and + maximumANDSum(stat2, nums, numSlots, numLeft - 1, mem));. T" p) G2 ^! Q+ ]8 J& x
}
; q5 I( I, b/ {3 H _) h. S4 D! z; X+ i- `7 U
mem.put(stat, curRes);+ I5 @( J1 c" s" Z3 i7 m% h
return curRes;* \7 _* t; {/ U" t
}# c" D3 b* j2 q
2 Z" D. d2 V8 c6 S; j, m. m
// i start from 1
" D7 h5 a* j* [8 B8 l. e8 z private int getSlot(int bits, int i) {9 R7 E% @& s6 z( K Z
int offset = (i - 1) * 2;/ d* a. i* X; ]4 W6 m. a& n
return (bits >> offset) & 0b11;
- s0 n& e" s9 ]3 k }
# }$ j5 `8 ^/ M/ t' C
1 i8 _; W/ ^* P. u" L$ { // num = 0 or 1 or 28 d& w D+ E% k( z
private int setSlot(int bits, int i, int num) {5 a0 u) \9 Z& E3 G" q' L6 p2 S
int offset = (i - 1) * 2;! T" D2 k- x# h R; x! Z
bits -= bits & (0b11 << offset);9 _/ }& P6 D: k3 Q
bits += num << offset;
4 B: E$ s5 g& H) J return bits;
9 F2 `/ b& g, L7 D2 C* Q }8 E) s _6 @- e. a
} |