登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】
! A7 C. J1 M. O1 X7 `8 a( ^( _- b4 ~8 M
解题思路
- d; I: K% w. h签到题。/ O5 _! }" W" P2 G- |: \
! o+ r+ V2 K& }" S6 L* w
代码展示
3 w8 f$ f9 |1 A+ k* z
# j, f+ C0 P! M( w6 Rclass Solution {' `! p+ D. ~- y1 X5 E [7 o7 m" e
public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {' Z& ~/ t- C! f, k
int[] count1 = new int[200];
7 q& A* t( ^% `9 @/ J int[] count2 = new int[200];( Y; b+ Y- V( G- c8 W
int[] count3 = new int[200];
9 j/ D% h) E, e2 }& X! P" S0 h# h6 N2 H" V for (int n : nums1) {
9 f9 M' A* L v' `6 {3 U count1[n] = 1;
) u- M" ^0 E( v/ i1 s }- U% K& ^" N" G/ k, i* I
for (int n : nums2) {
8 z O7 r3 H' Z. d count2[n] = 1;3 r2 s( Q9 Z* a. V+ u, a
}
* V3 |% D7 c! |2 e p: w for (int n : nums3) {
0 i8 r6 H3 J- q2 Q& ? count3[n] = 1;8 @6 j$ m2 r4 l: b* _/ J
}9 Y+ A; R+ ~7 U# o! L8 x7 {( Z3 r
List<Integer> result = new ArrayList<>();
: j( s1 }# s4 _: k2 N0 r. p for (int i = 0; i < 200; i++) {
; V, Z6 m e d: Q if (count1[i] + count2[i] + count3[i] >= 2) { o# N9 A3 R7 u9 R4 k8 d% {! A
result.add(i);% p3 e0 W$ w. I
}
~* m* X9 y% d: j! N }3 ~/ a+ }8 X+ k+ B, e* k; N
return result;2 u! n* U$ w- h) e
}
1 W7 C f2 O. ~. g+ r}( {" P o* L6 l
7 y0 q+ m( q/ k o3 n5 z- Q3 e
【 NO.2 获取单值网格的最小操作数】; _% w3 n$ R: i& b5 |
" m% r, t7 H7 X* e
解题思路
$ |9 F1 ]' ] J7 f网格可以转换成一维数组,然后排序。' C6 W8 G- d' ]* ^
. V+ P& x. M" f) Q# t+ R, j
不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。% d X1 ?% o- [5 p' I
6 y# R* l5 u/ \$ u/ N0 Z4 c然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。) q( j) E- y$ ]& q
& \, b& U% Y$ D1 t3 R7 A代码展示
) E! B7 w' z+ o; I
0 {& B% Z. n# r( dclass Solution {- a% E& t( c: b; j
public int minOperations(int[][] grid, int x) {
- V' `( c% m! s ^! p& l3 g int[] arr = new int[grid.length * grid[0].length];
# X! T( _4 [3 w6 t: `( [7 ~ for (int i = 0; i < grid.length; i++) {& C" E6 n# d% O8 E- |
for (int j = 0; j < grid[0].length; j++) {1 C# B2 H+ d9 U: ?
arr[i * grid[0].length + j] = grid[i][j];
" X+ Y" {) [9 K* l7 Y& ` }
1 f: M+ B: c1 o, q }
& w+ z$ o' a1 s7 v: c2 C4 T Arrays.sort(arr);
& ~! C) t0 I8 f- |8 {( y3 } for (int i = 1; i < arr.length; i++) {
$ B c# k7 B7 Y& u) P6 p if ((arr[i] - arr[i - 1]) % x != 0) {
J. J9 @8 p0 `* R8 L" `& g9 L return -1;
5 d+ w/ G. h4 y. i; Q }
7 U. R7 C; a1 N4 ?/ L }- ?5 h4 [8 d% }' K# A; o$ D
int suffixSum = Arrays.stream(arr).sum();) o/ `5 f7 s! H; `' l
int prefixSum = 0;
6 U+ v9 l0 }0 y5 w int result = suffixSum / x;
2 O4 K4 w7 K* U4 k% f$ }% _7 q for (int i = 0; i < arr.length; i++) {
2 i* n# s7 D' j) Y, f- n+ |6 f( A: q suffixSum -= arr[i];) [. V9 `* h7 D' x) w
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));: _, J9 [; b: M2 s4 `- S3 y
prefixSum += arr[i];
& v/ R% D; }+ L$ V7 `9 k, h- [$ Z2 Y }
& C4 [! V1 Y9 B+ x% t$ N return result;) h3 C$ H0 i. ` O
}
' z2 Q4 O2 L4 m9 a0 j
2 A3 R: c$ N/ Y! O+ g6 t- U private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {9 q5 i5 W% b# c' M4 ^
return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;$ R, s( `8 ?: U: c6 ^, o( I
}
. d, C: O+ N- Y! w% i}
! |* A# a2 I Z$ f1 u
8 E8 y; {4 C8 F9 f" [* u I! I/ d【 NO.3 股票价格波动】8 D% K& \1 |9 p% m1 y% W) g* Y* F
. O0 D2 z8 t( m, I4 C' J" X解题思路! L. P6 Y- X% J0 n; I9 g5 a+ A
使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。: R. q% p. H9 R, k" Y
* M. m! L+ J( t! ?8 ]
代码展示
0 d3 C2 v: P/ m2 U, F$ k% g3 _2 s! e9 K- v: L( Z
class StockPrice {
0 ?; c! `2 U9 ^' o
0 q0 w6 N. P% g, a3 f; s) f6 h TreeMap<Integer, Integer> timestampToPrice;( G s( Q% X5 d$ M* a3 W9 S
TreeMap<Integer, Integer> priceCount;" ]! v* |) d- {" K2 }
$ Y% v8 W- z4 g& N public StockPrice() {" Z; `/ T' k2 }( z' g6 O
timestampToPrice = new TreeMap<>();" j7 L5 x R# m4 M% l( j6 e P
priceCount = new TreeMap<>();
( \0 f4 ^! ^3 n7 Z }
f' u g& _+ V' u( q R- O8 R, ~0 t. b, r. L6 V
public void update(int timestamp, int price) {
/ S, ]2 e5 Q, B* T; @& H6 L if (timestampToPrice.containsKey(timestamp)) {/ q8 o; T* {0 f4 u7 }7 u% \
int oldPrice = timestampToPrice.get(timestamp);) [" C9 J' Z `1 u" n
int count = priceCount.get(oldPrice);1 ~+ w6 ?/ c+ `) z/ J" B
if (count == 1) {
) @; U$ m8 G) l9 D" p priceCount.remove(oldPrice);
; d Z: { `1 L* ` } else {$ d2 \$ _( |, `+ O: x j d* T* J; U# K
priceCount.put(oldPrice, count - 1);
- E0 a2 Z; L0 m( x* D }
8 C& J% P1 e( S$ R* q2 o }: Y3 D+ ^& J/ ^
timestampToPrice.put(timestamp, price);: Y3 B! E( \" M
priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);
. [0 _! w5 p N }( n# M7 a: k# o6 A$ G! t
! j' u6 L r: s" a
public int current() {/ _1 O+ E1 l) N( S+ w2 C e
return timestampToPrice.lastEntry().getValue();! V) } I+ j$ F6 e5 l: t4 L5 q. r5 Z
} q; j/ Y) A8 g. V$ I
: a% o' s d; z public int maximum() {
h" H5 @$ r2 @( L- U2 ?( k) r! O return priceCount.lastKey();( r# `+ B( \5 L1 {8 Z
}
/ P! _/ f) ^& U. }
6 V& S# b/ ~) u; n" F public int minimum() {. [( i' j7 [+ Y. }
return priceCount.firstKey();
2 a3 v, z# B5 [% Z }# \" g; Q$ }4 w. k
}
* v' ~( W7 D) U" }; A5 c+ u* M0 B
: Y$ v9 b+ O# i. x& Q/ v" H! S【 NO.4 将数组分成两个数组并最小化数组和的差】9 K9 G7 ^+ h" `. M! H$ W3 s. t
+ u4 _' }5 V4 H+ C解题思路
5 t% d- d8 X2 k8 O7 ?8 y6 X7 M; \0 Q/ [- I; h2 l! T, I
枚举 + 双指针,具体思路见代码注释。
) C3 z: t) [2 v' ^$ G
; O; p0 X4 q; L1 ]代码展示- D2 I2 p; r% k
3 G( P# {2 O/ d; ^ @. K" k+ ~class Solution {- h2 P+ E# {) {: ~
public int minimumDifference(int[] nums) {7 e7 m% S% z! q4 q* C/ D" H' h
int half = nums.length / 2;
4 ~' v H7 D" @" o' d int[] half1 = Arrays.copyOf(nums, half);) m" y0 I# p6 {
int[] half2 = new int[nums.length - half];
* p) N. G: v7 ~ System.arraycopy(nums, half, half2, 0, half2.length);# j$ `8 \; E* T7 y# a4 r- F1 ~
// sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序
; X3 H' {" z( \; P- N# ~+ O List<List<Integer>> sums1 = getSums(half1);
% I* x' R1 b! i- c List<List<Integer>> sums2 = getSums(half2);
9 r5 w, w4 N& V8 l# E int sum = Arrays.stream(nums).sum();1 E2 @" b* }* A4 s
int result = 0x3f3f3f3f;
5 r; W7 i: Q, b# x // 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个
4 U0 f1 o; {2 O3 ~& O for (int select = 0; select <= half; select++) {
; G5 p- A: G, W: t" B+ z5 q2 l List<Integer> half1Sums = sums1.get(select);9 {3 ~+ q* g" K( D/ a4 V
List<Integer> half2Sums = sums2.get(half - select);
. h) Z- ^0 e. M3 S3 Z // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2
. }* x9 C+ J+ ?9 P+ M) {' C. y& S int i = 0, j = half2Sums.size() - 1;
3 {! m+ [! s/ E+ v$ L8 M3 c4 w5 E result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
. w: z% a; G1 Z/ c0 I' T* q1 r for (; i < half1Sums.size(); i++) {/ I& A }+ B$ v* r1 ^* o9 }, g
while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {
6 j+ V, d7 g6 z; ~ j--;$ U1 N8 a6 A- b' F0 B& f
}% D9 M9 z0 ?* g9 r! u$ f
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));
& i0 l' J. u- F5 N8 { }8 |2 m5 {. u- Y& z) O e
}2 F$ I; s9 A2 `! d3 h, O8 x2 Y
return result;* Q3 o2 G; W1 r5 s8 w, w, _2 F1 v. E
}
$ c. W+ M% ~7 O+ f m8 k; L
8 P. d- @7 V1 i/ R( z5 U // getSums 求出 nums 的所有子集的和
h7 H5 f5 |9 N9 v // 返回 List<List<Integer>> sums
6 M9 y2 s# y X) B* j, x- g3 e // 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和
9 x& K O( |$ r) q% y // 去重并排序
8 e2 x) d: d* p private List<List<Integer>> getSums(int[] nums) {6 J* k% C/ j; Z! L6 u& x% N
int n = nums.length;
2 L' s3 S; w, w$ A5 I9 p9 H List<Set<Integer>> set = new ArrayList<>();" }9 d# j4 o6 d+ s
List<List<Integer>> sums = new ArrayList<>();, n: F* t( e; F1 K0 \7 G! A
for (int i = 0; i <= n; i++) {
6 ]) o, s% |) f& g8 F; T sums.add(new ArrayList<>());
+ g4 x# p6 W( d2 _ set.add(new HashSet<>());$ J9 w, X! ?8 @
}! V7 r9 I. A, \+ c, M* ^9 E4 [& n
for (int i = 0; i < (1 << n); i++) {
: [7 N. e9 j% i4 {6 j/ D( P9 ^ int sum = 0;
# }# f9 U& f" M Q int num = 0; _, ~5 g8 o/ {* ~* E8 K# F, i
for (int j = 0; j < n; j++) {# Z% Q6 R! Y1 Y( U' H
if ((i & (1 << j)) != 0) {
" m7 @0 {$ d0 q7 P& z sum += nums[j];2 @% u" b3 l3 Z! d
num++;( d, T" x7 Y1 V: O
}3 e/ ]% s7 H/ {/ f1 p/ g2 D
}1 N& T' o+ Q* U7 @) A9 }7 [& x
if (!set.get(num).contains(sum)) {
L9 G9 B1 x; d, k/ k set.get(num).add(sum);, |& n! }" ^; G6 a3 d! @+ M& t
sums.get(num).add(sum);
1 Q3 H) Y5 H9 c3 h) b% E | }
- v( M3 }( ?2 P5 O( [' g t K }
) F3 P. a5 J: ]1 N for (int i = 0; i < n; i++) {
0 e3 y) I8 t, B7 m Collections.sort(sums.get(i));
4 S9 s1 b2 `# ?; ?1 ? }* }% |; C: z0 {, t8 C0 Z2 X! j% l/ B
return sums;3 `/ S6 ~$ w. T/ K% U
}
' e$ ~& w1 x9 E- k; L} |