登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】7 l% ?$ [7 `2 ^# `, E
e& ?8 F2 D. }! e$ h" a3 g解题思路
5 G4 f5 A7 s' K( {. `( B& @/ o) ?签到题。 `) d* ~. \5 M8 I1 W
& q) [, }* b8 {6 h* n, M代码展示# L$ w* ]1 }3 L. n' T
, L+ C, N. ^) T& u; L9 W pclass Solution {5 ?& [$ `+ }4 Q
public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {
( I: z( ~$ w' e+ G int[] count1 = new int[200];- e$ a7 d# x: b) E
int[] count2 = new int[200];
$ B0 {4 N( ~2 F( R7 F int[] count3 = new int[200];% |+ L" ?5 @$ K$ Q0 \" s
for (int n : nums1) {
0 D3 @4 F3 E% A; u& Y" _ { count1[n] = 1;* H! D* o9 m* R5 W- O p5 M+ d1 |
}
6 T' F! A& g# ~5 o for (int n : nums2) {
( D. A- \6 D7 ?) D f$ y% z count2[n] = 1;, \+ X, _1 K3 T& M
}, v2 `, k+ @. f
for (int n : nums3) {
3 ?) G" O* p7 m0 d9 r count3[n] = 1;. c; k& e6 D9 @- h
}
$ Y$ C# P8 ~ S9 S( t5 N k0 Y List<Integer> result = new ArrayList<>();
3 r4 |/ d% Y, C. d for (int i = 0; i < 200; i++) {# l8 w; T0 b3 S+ D; s! x
if (count1[i] + count2[i] + count3[i] >= 2) {- D# d' w5 V" l2 D/ o* z8 a
result.add(i);- Q6 {- M# Z' k: K \' y; s1 k: J
}
* j& g a( k: x+ | }
" G: Z- [9 s% C1 S/ s return result;, l p% P- s, h \6 M
}
6 _8 d$ S3 @+ R- f" b}- {0 O z5 {0 e$ u9 {
/ N4 V! w* [/ _4 k2 l8 @【 NO.2 获取单值网格的最小操作数】/ P( ^" S& Q# u7 y; S! o: s% {8 u
: r* A+ K4 d2 m# ` N
解题思路
# r8 V( j# L. Z- O" D$ Q网格可以转换成一维数组,然后排序。2 p8 H: O: F5 L/ R* B! Z6 t5 |
5 ]0 r$ M0 L% T$ Y$ A; A" [0 v8 F不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。! p( [5 [9 L* i9 C# W
7 |1 i' { k8 W& `* }, c
然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。
: L: M8 j6 [# n0 K" T. f! U/ Q- p% B- W5 o
代码展示6 j9 _; W2 L2 g$ P; T6 p% K
* I' G, P2 ]% B! G3 `( [* Yclass Solution {' `! r0 v) D- a8 k: c% ^% J4 P
public int minOperations(int[][] grid, int x) {# n( c D, a5 A3 q- ~
int[] arr = new int[grid.length * grid[0].length];
( N9 P$ g% T+ n! ~6 \ for (int i = 0; i < grid.length; i++) {
6 e- K2 C2 ^* O, z U( i& J" a for (int j = 0; j < grid[0].length; j++) {
8 \: D& |8 I9 ?: `8 E* i arr[i * grid[0].length + j] = grid[i][j];7 S+ o7 w! O3 c0 @
}( K6 k9 v7 B7 X& ?- M9 w
}
1 d2 @. _# p% r1 B1 o Arrays.sort(arr);4 | V+ V. ~; w( F. [5 Q9 }
for (int i = 1; i < arr.length; i++) {3 }# f, ?% R& R: }8 j
if ((arr[i] - arr[i - 1]) % x != 0) {: O1 c1 S9 i+ ?7 O' o$ f
return -1;+ \" C* w4 y4 ?. f7 _4 |6 h" J
}; I- z: h5 |, E& U% Q
}) T6 V! ?' A7 T
int suffixSum = Arrays.stream(arr).sum();: m6 J9 D) @$ f* E7 M1 q
int prefixSum = 0;% j( {, y6 X% b
int result = suffixSum / x;
3 `. q1 `8 E; B8 B for (int i = 0; i < arr.length; i++) {
6 D- L- k, S1 z" Y. j suffixSum -= arr[i];
& f6 a9 m1 e1 J# }! |- H/ l1 g& ^3 D result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));
6 ]* l8 u4 k* B5 z. G1 u5 W prefixSum += arr[i];
) ^/ r4 D$ ]1 [4 a% x l! H I }
- i/ L# d& r5 ~ return result;
$ e& u J# Q7 O | }9 [9 ]) | z9 E
- T6 U" `6 k% B$ o" g6 Y1 C private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {
. N, L/ x* X* c9 ^+ P return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;5 z' u' U0 C/ R6 g7 B2 b9 P4 B
}- [7 H+ s7 ?, t1 T1 l, C9 K9 u, A0 f
}5 T. Z3 R S4 v2 i( O: e
& ~8 E, u/ f9 j
【 NO.3 股票价格波动】
4 e& g. D3 f1 T+ v
1 s/ ]) x4 y k" Z解题思路. b& ^* g1 D. b. Q
使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。
% p5 l6 r; ~3 L7 R: z1 F. K0 r9 v' ^3 L9 I
代码展示* U: t6 i" [0 N) ^2 ?% n
/ W, Z1 Q* F4 W4 d$ x: I
class StockPrice {# O# W0 ^# k' ?- c E. z' R4 T
3 ?) z* w( J# j6 o TreeMap<Integer, Integer> timestampToPrice;
; @+ v( K, E0 | TreeMap<Integer, Integer> priceCount;' W- r% ]6 C4 T- Y+ E4 T1 Q
' D0 S/ _( ?7 {9 z public StockPrice() {
; h j0 q/ S" V: `6 {+ I% j1 c! f timestampToPrice = new TreeMap<>();$ C. _2 u2 ~9 |# }" i
priceCount = new TreeMap<>();
6 n( ~, C4 v! G& g }
1 f1 v2 F2 r# ?
/ c: b( u( a- r% ?0 p) E+ a public void update(int timestamp, int price) {; ~0 d. b' ?# n8 g
if (timestampToPrice.containsKey(timestamp)) {
3 J. E* l4 W5 o& k int oldPrice = timestampToPrice.get(timestamp);7 }! G& i+ t1 G+ e
int count = priceCount.get(oldPrice);+ L& x5 N1 {" W# Q' L8 a- K
if (count == 1) {( A" z* ]: p& g+ S2 e# S
priceCount.remove(oldPrice);
( @# ?. ~1 R# ~6 Z2 w1 W9 m } else {
' {" Y0 Q, s# i priceCount.put(oldPrice, count - 1);
; N R% m8 l1 l, {* u }' N! T4 g3 e5 z' U) U D
}+ M; N, ?' N" z) H% |3 T8 u0 D
timestampToPrice.put(timestamp, price);
+ n! _0 T8 n/ n2 p4 N: ^ priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);
, Y/ V: a% ~# z/ W7 C7 o }6 L, Q- T( ~ d; J- t! ?) e
6 V) l8 Z" e G! p% f2 ` public int current() {3 j$ o5 L- u5 R! E
return timestampToPrice.lastEntry().getValue();
, o7 t- F; [9 s1 N' w; O }( D; q9 U' k+ u9 I. f
" C1 t u3 E+ N- s( o public int maximum() {
0 j: K8 Z3 Z1 D) Q+ C- q0 c return priceCount.lastKey();$ t: X* a( g; P- ^
}
* Z# [' [) B3 L+ S3 o8 ?
* k, D/ [7 r& g6 l$ V& }' L$ s/ k public int minimum() {
. L6 @ k4 v/ ?$ F return priceCount.firstKey();1 d* \& j; C2 J' M$ P) g6 T5 W
}
) F% A; ]+ k \- \8 ?}
, L2 a0 z( R- X' i! k) e( @; @5 s$ k4 k
【 NO.4 将数组分成两个数组并最小化数组和的差】1 I/ @7 N4 _0 ?
5 w3 X) t% Z5 q+ ~) V解题思路
6 v' U) q7 B' Q" ~3 W$ z9 y- O I4 D2 k, z7 E* S
枚举 + 双指针,具体思路见代码注释。
# \* f% ]- m8 d
9 L8 t1 g* b U7 s6 w8 W% X* S代码展示
0 Y' y j% K% B9 _( h
: q/ d9 D: N* hclass Solution {4 ]# [/ p9 Y8 V: c5 L" k
public int minimumDifference(int[] nums) {
8 n6 ?" {8 `) I& ~ int half = nums.length / 2;3 S% N% F* _. e' {- o' h2 F
int[] half1 = Arrays.copyOf(nums, half);' \& @9 g9 Y" B- W* T/ Y
int[] half2 = new int[nums.length - half];7 T' o1 c2 A% |( |% U9 J
System.arraycopy(nums, half, half2, 0, half2.length);
2 @% Y' W2 P+ Y/ S1 K9 X // sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序
! I7 ^7 g* g- n( z4 z0 R! _6 z; y$ A List<List<Integer>> sums1 = getSums(half1);1 q, F0 g8 D) v3 e# ?
List<List<Integer>> sums2 = getSums(half2); R7 a* e/ n9 X! k5 O/ e) h
int sum = Arrays.stream(nums).sum();% n* a0 }6 l% R6 T0 H' u
int result = 0x3f3f3f3f;: }0 O' e- G( g4 ~2 b. k
// 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个0 F' b, ^$ f0 m4 s
for (int select = 0; select <= half; select++) {
& u, L1 ~5 Y; u' a0 h7 [ List<Integer> half1Sums = sums1.get(select);/ [" H! B/ P# e3 S6 U$ y, I( `4 d
List<Integer> half2Sums = sums2.get(half - select);
* [! p0 u% h7 V, l+ L // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2/ o+ I& t- V" m6 `0 E
int i = 0, j = half2Sums.size() - 1;8 Y7 W9 d8 E+ n7 W: S/ \7 ? I* x; F
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
4 C1 _2 i+ g. T for (; i < half1Sums.size(); i++) {( J, s# W3 j4 H' B& T3 e
while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {
/ t1 |& Q# I. i; p9 J j--;. E, i3 p0 Z7 [$ H: m
}, G) I' _2 L- K" N1 @
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
! U# B. [7 x& A- V' w# q: ^3 `; @ }
7 H( ]; M" z. w' C( p' B }
3 [, c& H9 v- J* g6 A! c. s5 p return result;
$ _2 H w# P+ C* Q$ n0 _' E. m! F( X }( m0 e6 @- H- M) z9 z( h
y; l, ?9 c: H+ Y* m6 g. N // getSums 求出 nums 的所有子集的和& E2 u+ c0 P% k! j
// 返回 List<List<Integer>> sums) m1 v o! h5 A' J! o
// 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和
2 S& |$ B9 f' ~5 b // 去重并排序
! e0 a3 L6 G/ l; ]1 F) y private List<List<Integer>> getSums(int[] nums) {
( {3 |' Y5 p: ?8 J! n' D int n = nums.length;
7 F. G8 W0 ^" Z0 t- u& O% H% X List<Set<Integer>> set = new ArrayList<>();
; H# G7 J! O9 b List<List<Integer>> sums = new ArrayList<>();) C+ J4 B3 S, K) a
for (int i = 0; i <= n; i++) {
7 M: e( v1 @6 u+ I# E+ T( [ sums.add(new ArrayList<>());, w4 g1 U- P2 O# v/ M. S
set.add(new HashSet<>());
4 j% H) n# _8 s9 Y, [% ] }
. p4 s) k5 W4 t0 E4 d3 A for (int i = 0; i < (1 << n); i++) {
0 j i+ b6 D2 s7 L int sum = 0;
' ], E7 C. Z6 A1 F0 a) \ int num = 0;9 X8 t8 Q% r5 W
for (int j = 0; j < n; j++) {# @5 {+ u+ B) V0 b
if ((i & (1 << j)) != 0) {
; c* ?( b. H9 K( |+ l sum += nums[j];# P+ \( Q# y; {' k
num++;
0 C9 \6 d, {. x! [6 W: I" L }( d' _: A' r$ j* g: L8 j
}
8 W2 W6 h% i7 A# ^ if (!set.get(num).contains(sum)) {
/ ]8 Q: v! S& l: A+ b set.get(num).add(sum);
. \! J3 T& V9 H' \ ]# h& V sums.get(num).add(sum);8 S# R( W3 o3 {9 J2 ?
}, s, b$ Z Z1 q! \) K% p. H
}
8 k/ H. Z& T p) J for (int i = 0; i < n; i++) {
, Z/ {6 q _' ^8 Q4 [ Collections.sort(sums.get(i));
# X2 h; e) O8 L' [ }
6 y( o8 E9 n0 M4 K& W return sums;
. U7 r. Q: I3 y$ ]2 T$ W# w }; \/ l/ K* m4 C$ I L
} |