登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】
& _4 d% j5 w8 H
) ^, ^9 U, p( _/ ^; s1 u5 c解题思路* O3 q0 W4 q' T9 [$ j) T
签到题。
$ q h- M1 t8 a8 u2 b- j" |/ X' g. |% G W
代码展示1 t0 W! J# \9 t4 B
# @# v. f5 J. [5 |% k# X
class Solution {
' z% C% D' f! e7 q public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {1 J# J( g* p+ d
int[] count1 = new int[200];
3 V# O: s' w `8 [/ ^ int[] count2 = new int[200];. O! L a2 j! o
int[] count3 = new int[200];
9 e5 M* k4 i2 K- r6 X. B c for (int n : nums1) {
3 E5 ~2 m0 R4 z/ G count1[n] = 1;
! w9 w3 l0 h/ O% M/ z }8 F! M. _$ i4 A: o
for (int n : nums2) {
+ \- a9 v% {8 j count2[n] = 1;
: m3 z4 L2 p, C1 L6 R0 u- D/ [ }, S! Y6 H* U( I) Z9 s# U, ~
for (int n : nums3) {
' L1 [! L3 D/ ?8 D5 F count3[n] = 1;5 h, {6 }% z, F: z
}
" s/ h% z% Q' o* R: {8 A4 ] List<Integer> result = new ArrayList<>(); w' z6 l; D* x A$ L
for (int i = 0; i < 200; i++) {; Q; M7 d; Z. H* Z! C# ^6 ]
if (count1[i] + count2[i] + count3[i] >= 2) {
$ g4 C( H' {% S9 ?2 C result.add(i);6 Z& }/ ]1 r6 N' S* d! ~3 J
}
5 b) F- o" s- K( Y: `9 J }# h/ e V: R! q/ o/ o& g0 q: y
return result;; o& P; ]+ v& g8 C# m
}% D& L+ e0 u1 p/ x, q
}
8 l3 U5 K$ W! o5 k3 Y+ R: m! l1 r- `0 b1 @5 V& l% d" H
【 NO.2 获取单值网格的最小操作数】
' {( z) Y4 h: k$ d/ H) L' B, _; a. v# K5 @. Y, t4 O
解题思路5 j- f/ Y9 h5 T' d$ i- H
网格可以转换成一维数组,然后排序。6 o, y1 S$ ~- I) h9 h. ~
& {, e: A, c* ^! s/ E! q) P不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。! e9 G7 x5 K& k9 T5 [
- y0 @- C/ E8 ~/ l, \然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。2 e. T7 b6 f8 r& p$ `
- q! F3 I4 l: a0 ^代码展示
, p! ]! `1 f _8 V8 N
; E4 O# a* J9 qclass Solution {
$ |# R1 G4 z& k- T public int minOperations(int[][] grid, int x) { U2 w2 m* o' ~0 J; W9 A
int[] arr = new int[grid.length * grid[0].length];
' A2 w& G7 A) Q" ^ for (int i = 0; i < grid.length; i++) {
A( t0 n" x; G( u for (int j = 0; j < grid[0].length; j++) {
6 `. L y+ _" d) l8 J& n arr[i * grid[0].length + j] = grid[i][j];
6 Y$ G9 ~( Q7 Y T }
6 l8 f& N" n0 z4 V }4 V5 j+ t; s/ h/ Q8 A# p' R& _
Arrays.sort(arr);. x1 `3 @/ M/ J6 g. {& P, \6 ?
for (int i = 1; i < arr.length; i++) {
' k1 y+ ]% N8 P V7 }) v if ((arr[i] - arr[i - 1]) % x != 0) {5 f" W+ t) h4 I/ ~
return -1;, A8 O) Z e& G' I, X) S- t
}$ e8 Z/ q, O1 S7 f' W
}
; e/ D5 D% r; G1 q2 U7 _ `' v int suffixSum = Arrays.stream(arr).sum();: B2 Y$ ]% w! V+ v$ V, o
int prefixSum = 0;0 b$ U. c# [6 Z! [
int result = suffixSum / x;
& M V, {. v8 ? for (int i = 0; i < arr.length; i++) {% D* I5 M: g& X: I, q5 v
suffixSum -= arr[i];+ p3 o6 L9 h5 w4 k$ h2 C Q' w
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));
; z$ r" D, L9 f/ @ prefixSum += arr[i];
. v& S& k+ t- D4 E }8 t- `# I( S. y1 b
return result;( C2 V4 Q: F7 ?
}
! Q7 o4 l2 b9 h( k. Y2 `0 x% R- e* S9 d8 m7 I3 B- v4 c: i
private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {
. ^4 o1 u8 \/ I$ f. ` return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;9 j/ O% g& f4 a7 ]
}; I# j# ~5 D( U/ C$ ^/ j3 o
}/ z) B% g3 e* ?4 w5 B
$ j9 R& P5 e6 V【 NO.3 股票价格波动】
; R! E0 w$ r5 G) f: |% J2 u. e x( R l; V. ]6 V4 C# ~ }( [5 J/ r% u2 r
解题思路/ D9 z( N% B( d
使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。
' |$ Z1 ~* ~( d- a8 x) ]- c
& r# ?! Y3 O' A3 S/ Y代码展示
* f2 l6 I9 z: C) W( B+ j
8 T- T1 M2 W- `" F fclass StockPrice {
" [: b. C9 r" H2 q! u; k# F! x; u8 ^0 q# r; A" C' q. g
TreeMap<Integer, Integer> timestampToPrice;# Y; p3 E6 X3 h" d
TreeMap<Integer, Integer> priceCount;
( I* ~& g: Z6 a$ Z t3 S' ]
% Y7 y# `4 x6 a$ f+ G W, K public StockPrice() {4 ?# J/ F: y" e3 ?6 @
timestampToPrice = new TreeMap<>();* }! Q# V6 s' h) ?
priceCount = new TreeMap<>();
, e8 r2 N& ?+ E1 W' Z2 C }
& I, s8 U7 O' ?* m( f( }
$ Y9 L/ T! P8 e. Y3 {: A) @ public void update(int timestamp, int price) {
- r$ M' W* k$ F7 u7 o9 j- ?1 b if (timestampToPrice.containsKey(timestamp)) {- L C, x! F" X* [
int oldPrice = timestampToPrice.get(timestamp);" v' f$ D" a- `7 e9 L" L! {( x
int count = priceCount.get(oldPrice);- G) _- ]2 n# g6 n- {1 q2 B
if (count == 1) {
7 {- m, r& G9 H: h4 S0 j- z" O priceCount.remove(oldPrice);
; `. r0 S* v$ v } else {( O U- \8 u4 C. J
priceCount.put(oldPrice, count - 1);+ F) \. U1 V& M, e' V E
}9 P: y8 S- m0 s" C8 b7 s* d; Q$ g
}' a/ [0 E9 f& M
timestampToPrice.put(timestamp, price);9 ]& A8 v! a8 k0 d
priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);
; E; L! ~- C) N0 H/ g- Z }: k- \( _/ y5 z' |: A. n! y6 k
' V. E; R. M* @, A; l! P; V
public int current() {
) ^; R4 \# ~" ^4 T$ { return timestampToPrice.lastEntry().getValue();$ b6 p% _5 c) a R8 B
}" F' s- Z( u& E4 d% w
Z+ {$ J2 K* t7 D3 M, t
public int maximum() {: f: G* C3 J5 u
return priceCount.lastKey();0 A" i9 F3 w. q
}
& h: L$ G* Q* c: J, y; [8 A2 s/ t0 K5 m8 T( b
public int minimum() {* M% E! ?; y x7 g9 b" U1 M: t% w
return priceCount.firstKey();; `# ~# Q1 o+ j t+ ^+ L+ P# S6 E
}# [2 A5 b5 [5 I. u9 F" [( s; o
}" W! e/ S# S6 V- X2 ~- c; Q/ Z. v
- R j! V+ i" g- g0 d/ K8 z; V; N
【 NO.4 将数组分成两个数组并最小化数组和的差】
$ W p6 x [6 L& g- _/ x; U
9 z. Q9 j! v0 W" I) c解题思路( l! H9 B' w2 E$ L
u. ]7 C) `9 J- r! R0 p
枚举 + 双指针,具体思路见代码注释。' {1 ?& I+ E' A$ N- m, M4 N
* B5 X/ u4 p9 G# x' l3 G( F代码展示% G. l5 S* r% w, K" }
7 }% v3 g" z& @! G7 `' gclass Solution {9 ^2 G+ m! |6 I/ Y, r$ a; U9 }
public int minimumDifference(int[] nums) {
2 W/ u1 P( b. ~/ a6 V+ s% t int half = nums.length / 2;
y( F* Y0 s7 w/ d& {4 p int[] half1 = Arrays.copyOf(nums, half);6 V c4 {% L, h, ]* g- v0 w" t% A
int[] half2 = new int[nums.length - half];9 g# q: m7 \+ W" K0 [" \: m
System.arraycopy(nums, half, half2, 0, half2.length);
* H+ \3 K+ D: { // sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序/ ]5 L2 A4 z2 `: |; V
List<List<Integer>> sums1 = getSums(half1);4 @: y4 k8 B4 W5 ?" ~' y8 c
List<List<Integer>> sums2 = getSums(half2);7 X/ D3 h, u2 ^0 b' J: ^6 Z
int sum = Arrays.stream(nums).sum();( f# e( _' q3 {5 E9 S$ U
int result = 0x3f3f3f3f; G2 S! m" B, S" \) k8 p! W1 a& j
// 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个+ b* \, e9 x2 b8 r5 f6 `( T0 _
for (int select = 0; select <= half; select++) { @' d A& e* x( m3 y% ?9 M
List<Integer> half1Sums = sums1.get(select);
8 Q1 u5 j, M. X0 N List<Integer> half2Sums = sums2.get(half - select);
, e: U8 @. B) j3 Y- [ // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2
3 x' y! q6 p8 L1 R3 R% Q int i = 0, j = half2Sums.size() - 1;2 {$ g8 U0 L$ I) F! B
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
2 S/ x" S" A' { i) i! g6 ? for (; i < half1Sums.size(); i++) {
! _* `, W6 p) e8 K while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {
: O; N' i( K6 P j--;. m" m# Q" ~/ ~% a) q
}$ K) O; g8 q; ^3 G
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));. ]/ B; S4 {& v4 ~; v
}- e" T4 ?0 P2 L- f" p4 u) P
}/ Q0 Q" a7 V) v4 }8 s, ~( E. X: \
return result;2 B" A- R% X3 E2 X! B/ }
}
1 y9 T8 s; i5 I4 m( \: G1 M
! ~( B) ^9 f A* G6 Z( C4 D // getSums 求出 nums 的所有子集的和
c s8 I& W' |0 b" u+ G$ V' Q // 返回 List<List<Integer>> sums
) D% o$ B+ A) p7 L1 }3 H" p! K // 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和+ W6 k3 k+ W0 @2 b2 N0 b1 M
// 去重并排序, w0 L0 z. x& d: [% N
private List<List<Integer>> getSums(int[] nums) {
3 p# t( R* l$ c, G4 D6 y# o9 M int n = nums.length;
' v2 t, D/ l6 _- ` List<Set<Integer>> set = new ArrayList<>();0 E% v4 j" [& t' j! c
List<List<Integer>> sums = new ArrayList<>();
/ w4 b" w% Q1 P+ @ for (int i = 0; i <= n; i++) {$ a6 k- q( H2 c% G+ ], d0 O% ^9 f( \
sums.add(new ArrayList<>());
) h# }* R' V; R; a- K/ Q5 { set.add(new HashSet<>());% |. `. W9 ]7 {* z( o
}
7 ]( [. [6 K% l/ d for (int i = 0; i < (1 << n); i++) {
- ], M) N: B/ u/ Z7 y/ ? int sum = 0;
) T( a, }. f% F- f int num = 0;
J- Z% ~- c4 }0 Q: Q; g for (int j = 0; j < n; j++) {
1 F& @1 }3 Q) R }# \3 _) z if ((i & (1 << j)) != 0) {" [! Z( C _6 z# j
sum += nums[j];
$ _' {9 j1 A$ a8 ^$ Q num++;
0 Y3 t- V& \, ?9 k }
1 e* s7 P9 ^3 D/ [) `2 p }. v4 l' I0 M( d! e- Y7 z- u
if (!set.get(num).contains(sum)) {% m1 l8 v' g; g: }1 ]4 H
set.get(num).add(sum);
3 r/ X: L! n( v5 O$ m" w sums.get(num).add(sum);0 Q' b! @! D( ]# j! D* I
}
, z# I5 i6 L2 @ }" ?; Y( _1 J5 L( W3 B
for (int i = 0; i < n; i++) {' V/ ` Y2 A2 \8 \4 X
Collections.sort(sums.get(i));9 D5 M8 h5 H: w4 S* f0 l0 A
}
3 f, F3 _# r% j! D; a( d return sums;
+ I. @& D2 s3 G& L3 k3 r4 F }
4 l. R k/ B+ J6 K} |