登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】. c0 [, p, }% Q) ]/ h6 `
+ n. E5 n4 u# z) `! `- B: e
解题思路
& s0 G1 H! \- p4 a9 _- _. r( ?签到题。, K. S: |: u" s$ e- p5 r: g# v3 c
6 |1 u/ s) s$ G! w; ?+ ]代码展示
5 y, L( V! _0 h7 \3 Q7 Y
5 H; L- @$ v+ Bclass Solution {! K$ q; @/ c, P' s, w
public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {
! ^; M0 P( X& F5 p c6 }4 m2 G: I int[] count1 = new int[200];
7 d( m- H. K, X7 `4 R int[] count2 = new int[200];
4 V9 V& P2 C7 u' J. ~; V8 c8 o int[] count3 = new int[200];
7 M r! u7 H: G' t5 l for (int n : nums1) {
( _* b* f0 W2 i/ f3 [/ a count1[n] = 1;
& G% I2 J- Z! Y }8 _' i, q. b" Q- O
for (int n : nums2) {/ U8 K& T& E. V, V
count2[n] = 1;9 X* Y% y! N( J) u5 ]: v [
}
6 L9 v9 t: R, \$ E+ i3 U; _ for (int n : nums3) {
" o% J0 y# r2 h: R4 t count3[n] = 1;
0 i9 O. k- f3 p3 d- l& s1 m }9 z9 w6 D4 {' M& q6 e% I3 R
List<Integer> result = new ArrayList<>();) q/ Y k6 s) Z* q" x4 Z
for (int i = 0; i < 200; i++) {
& H7 d2 e+ j! Z6 r- ~! i if (count1[i] + count2[i] + count3[i] >= 2) {( N- ~& u. m+ U- h# ?1 m8 Y3 r, Z" H+ K
result.add(i);+ _" M; Q4 g4 R/ q$ H0 \5 h
}% ]) A* n% C6 m! Z7 I4 u
}
8 `8 Y- D, o& m8 N return result;
# ?" y6 s: j- o- G5 U/ N }5 [2 u2 ~5 d7 _
}
& ], z- F. L* ^# K# r5 a; w9 X% B1 N
【 NO.2 获取单值网格的最小操作数】8 ^5 V; I3 g5 Q# b
0 @ K, Q5 V% O P
解题思路
* h2 k. [1 |1 r( G; _网格可以转换成一维数组,然后排序。9 d \& `+ g. \+ u4 @
; |) Q/ l2 C9 W1 ]5 w不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。5 i; p8 t) ^% k* F4 N& \& E2 }' e( T
; z& _+ Y5 s6 J5 Q2 R
然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。
2 q- o) l0 \6 c1 v# J4 f& z
0 n; E( |4 f% U5 [* z# Q# k代码展示0 U- v% M/ U+ M, q' N* H7 ]
" H' ^! T/ }) P" I8 j8 t% Bclass Solution {
) O" f6 r( P' k- ]4 R public int minOperations(int[][] grid, int x) {" E# t( I( k+ w* q5 I0 T" q
int[] arr = new int[grid.length * grid[0].length];- f+ @% p* O& Z
for (int i = 0; i < grid.length; i++) {
5 I( p( Y' x" `# w. ] for (int j = 0; j < grid[0].length; j++) {
1 O. D( o% \6 b# d( Y arr[i * grid[0].length + j] = grid[i][j];$ y+ p, m5 B) R- J5 P5 J
}2 u3 G8 w0 v0 ~1 u2 _* [+ D" b
}; V8 J, P Z8 ]2 L
Arrays.sort(arr); Y/ V; V" b3 A) H
for (int i = 1; i < arr.length; i++) {
2 @- N! @. ~0 m5 O4 B+ t if ((arr[i] - arr[i - 1]) % x != 0) {$ R7 M; m6 ]% c4 P8 N# J& r$ C
return -1;
) c7 z7 E: D% b3 d' ^ }( ~& d' Q+ _! D1 g- Y3 f
}- G' P- b7 F7 r# O" v( A
int suffixSum = Arrays.stream(arr).sum();, W: V4 o y9 @
int prefixSum = 0;- |7 ?1 t( D i& K& K% Q
int result = suffixSum / x;
& v$ a: s% c* c5 ^1 f% z( K2 X for (int i = 0; i < arr.length; i++) {' U4 b L8 k( A, B; r/ p G3 t2 F
suffixSum -= arr[i];9 `2 T" e: E# g2 h& ^& e0 f$ O
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));, s% Q7 [$ v2 Q# B; }, g1 g: T' m
prefixSum += arr[i];
; M& H/ e6 m$ }" h; y l! y9 S' W" ^ }2 W+ m5 M; A- g8 E9 }
return result;
, E( X) @) q( U; m9 E; p }+ G& F& U: ] b& U' L
4 K# N% Q6 i) p
private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {
5 }% p2 t) Y8 w& G9 O return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;
7 \# m/ G2 ^. Q- U/ w- q& k- h% l }
L! G. r9 g1 J}
6 ?2 H2 o! D& N5 }' [8 c2 [& k. E5 k# F$ ^- f
【 NO.3 股票价格波动】
M; J7 k. g. h! ]( J Q: y4 Z
9 S, y( [) C0 g8 k* t; x0 ~解题思路 H ?' f& J. H' E# X
使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。) e3 j c! Q; [9 }' ~
i- k7 ^7 N z2 o( x2 E5 {4 E
代码展示2 o9 |) C+ y4 n/ [0 ]+ Q, D6 S' A
j9 X2 C2 L4 ?6 A/ V
class StockPrice {
: X* f+ ^+ ?1 B. Q, V% @
5 H9 X5 m0 O8 t TreeMap<Integer, Integer> timestampToPrice;0 R1 Q9 p) s: U. P& ]
TreeMap<Integer, Integer> priceCount;2 P' {+ z. v' J% {; Q- E" v4 G
3 p+ _7 l1 E; R/ Z5 X, y. h0 k6 \ public StockPrice() {) E" X# D9 E; I9 Y, b
timestampToPrice = new TreeMap<>();& s( m2 F1 [1 \5 ?& u+ l
priceCount = new TreeMap<>();* K' a! e0 S4 D: g& c) w( T
}, E6 N5 f- O6 L+ w
) a/ \: W2 h+ X1 x public void update(int timestamp, int price) {
; K* @3 m" ]: |& K4 R1 w) q if (timestampToPrice.containsKey(timestamp)) {
7 g) B3 X6 h A1 F2 B+ ] int oldPrice = timestampToPrice.get(timestamp);
0 n! ~4 d! ^2 L+ |6 n! V int count = priceCount.get(oldPrice);
- a/ D1 a0 J' ?2 |& I5 _( _) Z if (count == 1) {& k8 {) b- G' h+ ]5 v' `7 Z- y
priceCount.remove(oldPrice);& [# P, T4 ]; H5 p. D" c3 q* k2 d8 K) M
} else {! E$ p. \/ ?9 E( M1 r* `( n; ^5 ]* ?
priceCount.put(oldPrice, count - 1);7 J: [& K0 L2 V: `1 I3 f5 K, u& p
}
; ~4 V" B: C9 V }5 V1 C" d5 q0 O5 }+ J
timestampToPrice.put(timestamp, price);
- F' T/ M8 V k { priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);/ P- \8 N! g4 f6 x4 u2 i6 g
}! r( o0 [6 k+ Z
7 ^" o3 Z3 J: D- ~0 D9 Q+ S public int current() {
$ B+ j7 J, ^& c; s; Z9 k4 ~ return timestampToPrice.lastEntry().getValue();
4 G* C8 t/ S9 A' f7 M; e- T }
; M# B" ~4 S. S- w. [/ T! l& W
' D" b! s+ e# x" {& } public int maximum() {
& W$ }: F1 N$ C7 @2 y* r( c return priceCount.lastKey();
0 Z8 f* u$ Z/ V9 Q9 Q }7 I4 ^" L, }& {# F* T5 q. L' I
# q4 ~0 Y* F/ V5 Z \, U3 K6 U public int minimum() {) ]% {. H* f9 A% P; @, |+ x
return priceCount.firstKey();+ ?' x3 B* M& }3 E( g* }
}
% C% z I, b3 L}, N+ Q5 z6 h2 k* O& D1 y
+ U! i% r, {2 w9 i6 f% U) X4 K【 NO.4 将数组分成两个数组并最小化数组和的差】8 y* `6 _( ^& }% `' H4 ?# U
' J K! P/ i E. f* Z解题思路
- |4 h0 t! F* F: j$ o
9 ^! F( V/ b0 M5 b- r8 C4 C9 W枚举 + 双指针,具体思路见代码注释。9 o! ~1 ~. U8 Q
' G0 S2 X7 O( [ a, I代码展示
; Z( X2 ^+ q/ [$ c, l4 u
! c2 d0 h+ Y8 M- a! b4 Yclass Solution {0 d8 P G8 K2 k3 v1 F4 r
public int minimumDifference(int[] nums) {
% C( d9 A" w/ \- P$ r/ j* K/ e int half = nums.length / 2;
& W; S. n! R* G# | m8 a int[] half1 = Arrays.copyOf(nums, half);
& N0 ?9 T: |( n1 M int[] half2 = new int[nums.length - half];
/ {* y |. X1 O, g# R System.arraycopy(nums, half, half2, 0, half2.length);
) } }3 y( l9 B // sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序
2 y D9 t2 a: \( k0 x, p! Y3 q List<List<Integer>> sums1 = getSums(half1);
8 c) @% W# F9 v List<List<Integer>> sums2 = getSums(half2);
( o. K# f" g1 a: e( F0 \) R int sum = Arrays.stream(nums).sum();+ c; S+ _$ [# W4 n
int result = 0x3f3f3f3f;4 L, C& N* D4 L) {
// 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个! B& K# L$ T2 p. u
for (int select = 0; select <= half; select++) {2 {/ n5 l) Z, y* _* t0 `
List<Integer> half1Sums = sums1.get(select);
8 | ~4 L) ?/ q List<Integer> half2Sums = sums2.get(half - select);
: ]- R4 d! o$ b% h- t; d // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2
, {: [6 [9 }( P* v6 i int i = 0, j = half2Sums.size() - 1;" a. {3 o! `& U0 u5 n9 c
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
* D( `% e* [3 w( ? for (; i < half1Sums.size(); i++) {" U* g8 M1 ~3 [$ W A/ k4 r
while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {
$ B8 b9 B1 J j7 x1 B j--;0 d1 w4 p/ n5 _9 R2 @! H6 {4 ?9 Q8 v" f
}6 m" ~* l2 S P: F6 D# L
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));9 v2 E# A- \/ N6 Y
}
; R; w4 @) ]" F6 l: O" R }
# Y6 h6 o0 ^9 n6 _- P# d return result;
* ^% T% J2 }" Q: R; u7 J }
9 Y' P& S0 _% w& P2 T j2 \; J! {+ \ H& O7 f
// getSums 求出 nums 的所有子集的和) J, B; h0 I2 i& y" C
// 返回 List<List<Integer>> sums3 V5 R5 Z$ x/ E2 u; T( T
// 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和1 I4 Y$ g2 V$ ]/ ]% ]
// 去重并排序
+ o5 ]4 O. ^1 e' Z s private List<List<Integer>> getSums(int[] nums) {2 ?* e9 s0 a+ M- Q2 v
int n = nums.length;( `" j! V! H% Y! `- d
List<Set<Integer>> set = new ArrayList<>();
6 ~! p* _6 z6 p4 p& z0 S9 w0 @ List<List<Integer>> sums = new ArrayList<>();$ c) F- e( k5 h+ Y+ ~/ y( x
for (int i = 0; i <= n; i++) {3 T- n) C- N. S6 z
sums.add(new ArrayList<>());9 G( }. Y# [# a' n
set.add(new HashSet<>());0 T" E! V. W" B2 S; h3 l
}
$ B' Z9 W8 X0 A, S/ U for (int i = 0; i < (1 << n); i++) {: F5 m& U0 T) _& f6 s
int sum = 0;' Z; R* p. k2 Z) [, M v" L
int num = 0;
) u# x5 x: _6 R' ` for (int j = 0; j < n; j++) {
, P4 H! Q1 c# X0 v" R if ((i & (1 << j)) != 0) {
9 x0 g# @* k' ?7 w0 U sum += nums[j];
& y( M; K" s! r' m" J num++;
* q+ y* J% F9 d' ^* h) z2 R }5 t& K: ]& {- i8 H; b
}
( g4 I$ K' `# C& i if (!set.get(num).contains(sum)) {
1 t3 `: f _# T- S. c6 U set.get(num).add(sum);+ p- A8 o' g* L7 o6 @
sums.get(num).add(sum);: v2 D. j; b4 E% ~& b9 } \, B
}
. H) b Y( o. R, ~, d$ D, u O }
: ~6 ]6 X8 O; D for (int i = 0; i < n; i++) {# D Q5 m* w# f) o# n0 N8 Z
Collections.sort(sums.get(i));
5 e5 `& H9 P. ?1 V/ Y0 P1 l }
1 ?; u7 X! @$ b$ b return sums;- A) f& a6 D3 k
}
; M% u1 y* ]- l& t' } i} |