登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】7 l) @0 D4 W8 E4 z/ U9 S
, t4 `, |* b; q- S' w/ b+ t) f解题思路
. R9 z) T% k7 k( Y2 ^签到题。
& N V S( F6 a% t: K l- o' ?
& I3 L) Q4 r+ ?) h( S代码展示 y* I* N# E. C2 y8 ?) z7 d- u
) V, w/ D' [* c% [
class Solution {
& m) ^: A; n/ S' H. b! q/ S public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {
/ N+ e6 O8 N- _7 c8 x: W int[] count1 = new int[200];
( v. w$ x# [" X) y int[] count2 = new int[200];
8 L8 F6 \* N, @ int[] count3 = new int[200];
* E1 G' V$ f) y" R0 l; |0 } for (int n : nums1) {
- \$ P8 |% D; s- [) q s count1[n] = 1;
: a/ H& x- K C# C' \! Y( S }, ?; m: J( j, w* o
for (int n : nums2) {3 V0 ~: X1 j# s" a) j
count2[n] = 1;/ D/ n4 a- M* g( b* [ ^8 ]
}
" c! D: H$ }4 y( [/ x$ Y for (int n : nums3) {
3 O v* ~2 S9 n# _8 p' l count3[n] = 1;
' [7 c# I/ m4 E2 O }) Y% y& g, r, G: c
List<Integer> result = new ArrayList<>();2 J; I! `; {& F- n+ a1 v1 t
for (int i = 0; i < 200; i++) {# Z# w, Y& @5 ?
if (count1[i] + count2[i] + count3[i] >= 2) {5 I& X. l+ E; g) e' i6 }
result.add(i);
; O+ k- @+ @ f' I3 A. t }' N; k: \; p& S: H* ]
}. D: N! g4 ^) {/ f( x- n, O0 e
return result;
! I2 B: X/ P4 z! y/ G8 C( a }
0 K0 ?& p! ^+ t# P% d}
8 `( }$ Q7 E' C% V0 ^
* C0 b; C4 ]# \; _$ G【 NO.2 获取单值网格的最小操作数】# i% u& U' w( A% S# u% ?
9 M9 z' ]0 x+ b0 L& l
解题思路
% C& G$ E. K; I. ~网格可以转换成一维数组,然后排序。+ |# E# |/ x' @: }
s' o3 Q' O5 S. Y6 P
不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。3 j) d5 Q4 Z8 u. Z C4 |7 W; ~0 n4 N
4 U' A5 U- ~8 Z1 U; P w
然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。8 G+ C/ j8 k+ Y5 J/ K& t. d
! w. p6 ~2 p! i( M2 q0 ?% [
代码展示* B& o+ o& c) Q* u9 \4 r, F1 g
5 a. h( d, D _* f/ g$ v
class Solution {+ m1 ?# w$ E$ c* x4 ^
public int minOperations(int[][] grid, int x) {$ Z; r* T0 X0 W% c6 j3 }9 X( B
int[] arr = new int[grid.length * grid[0].length];
, A( q1 n* y( u0 ^ for (int i = 0; i < grid.length; i++) {4 X) u( o: F/ P* ]" M% T+ E5 \: w
for (int j = 0; j < grid[0].length; j++) {- N/ `+ w: y: H6 E5 ^0 g% @
arr[i * grid[0].length + j] = grid[i][j];
. o& H$ N* y2 l2 Q( f: Y }( u: b" T4 K4 z5 X$ f, D
}3 d7 D7 w; y5 M0 q
Arrays.sort(arr);* H3 f$ y- t9 x
for (int i = 1; i < arr.length; i++) {
3 e* l, p+ P4 D$ r5 h: n if ((arr[i] - arr[i - 1]) % x != 0) {' e5 u; T e0 P, { E3 R
return -1;
( D. M! ]1 n! C8 r' l7 Y0 S }4 p7 m! \0 c+ B' C7 `' |9 ?
}
+ }! l& s) v0 D: v! R/ s7 M' l int suffixSum = Arrays.stream(arr).sum();9 z* I2 u5 M. t, f" V) a3 `8 {
int prefixSum = 0;: v* n3 e6 {3 y; }' v) w! V$ y
int result = suffixSum / x;
* h! n' x8 T' P( W" X" W% U% Z: x5 j for (int i = 0; i < arr.length; i++) {; I6 j/ A5 [- n2 \
suffixSum -= arr[i];3 w. t3 Z+ K1 G$ g: ]. u
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));; U& j7 A7 y- D5 c' V
prefixSum += arr[i];8 m' t$ m |$ }
}5 k0 l/ ]+ l6 Y5 Z" Y& `! K1 K0 O
return result;
) c8 Q# y7 t% m$ r( Z4 s5 [ }
7 ?4 ~& p3 z" y& h' o q8 C6 ^* [( s, R
private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {* L/ d5 R) V% L; Y% ]" \: d0 f
return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;
! w* w3 w, x/ Y4 F4 U4 g } {" l8 \ |" N: q+ A
}) I/ w1 m# G! H- f
8 ]' B- O2 A4 R* N6 n【 NO.3 股票价格波动】6 X7 z* i$ t( f' V* x. z; @' f
0 f% ^' Q$ B* l* u解题思路
, ?! E9 S8 i" i, F使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。( D2 y+ {3 U' S' r8 `7 O
: z: S) E/ \! n, a) Z代码展示+ s. P8 Q; t: n+ y1 H U
! t# K( U( ` [: |2 Zclass StockPrice {
) U3 J5 q! Z% x/ D0 y4 n2 o; u& g) c2 l
TreeMap<Integer, Integer> timestampToPrice;
- g; n2 b7 g0 f0 G6 g% S- _$ i TreeMap<Integer, Integer> priceCount;
* W) z, l; h9 N6 I- V$ b. A
. t N7 @9 O( r' C public StockPrice() {4 ^6 F; x1 G/ C2 w! g* l
timestampToPrice = new TreeMap<>();
+ l* A8 L! ~) {; R; S8 D j: g priceCount = new TreeMap<>();9 T2 }& R, b* M$ \9 ^
}
$ l7 Q# w: H9 C( X8 ^
, s- N! B) s; ` public void update(int timestamp, int price) {
, `. \, `) |# C8 _; x5 \' ~ if (timestampToPrice.containsKey(timestamp)) {/ r; A2 G% T% c' x0 q$ y" I
int oldPrice = timestampToPrice.get(timestamp);4 q% h2 @0 A* `, k/ H3 A0 P" o
int count = priceCount.get(oldPrice);
% t4 A% U2 K# f$ N5 ?' S if (count == 1) {7 M0 X$ n, P' e1 M
priceCount.remove(oldPrice);
$ v) b" { |1 |% |* N } else {- j2 |2 t) h$ x1 j: h' K* F7 S
priceCount.put(oldPrice, count - 1);
" ~0 w- H o4 M' m6 a7 a6 r }( `: F( g# s2 V
}
, _" ?- r$ ^4 s: S" n timestampToPrice.put(timestamp, price);
6 H- K7 p1 q! }! y4 L- l, v priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);, z3 r F/ F3 V: o8 A6 ]+ I" a
}
5 T' o; B+ R% G! G1 u0 A0 C' y o, M) T! h
public int current() {
' A! U) { d* q: f return timestampToPrice.lastEntry().getValue();8 b: {- H6 m8 z
}( g( R2 G* F. f6 b4 ?5 f4 ^
+ J p# H8 R0 @& Z public int maximum() {
2 t2 z0 N( P0 V; o k( t8 t: | return priceCount.lastKey();
# H" P4 x$ g* u* h9 u) \: A1 [* \ }" a) F, L* \; u7 }7 s) p& G
; [) x. M/ _0 w, G
public int minimum() {( }7 ?+ B2 t8 I: M- Y/ Q5 s
return priceCount.firstKey();, M1 N, `8 D( ~+ @% p
}: Q2 A0 L( Q+ d) \
}- Z/ a |2 Y6 d/ p% D8 l4 b* A) i
/ }* D+ S. H* _( k
【 NO.4 将数组分成两个数组并最小化数组和的差】8 b$ \* u v7 Y* S( D' p1 J* _$ [" g
8 R- u( e& ?7 J" u+ P; Z
解题思路/ w8 k; v6 N( I& w& {3 j5 v
- W+ [3 T8 L- I1 H. c/ B
枚举 + 双指针,具体思路见代码注释。
* D0 i! l% K) c
0 B j& F# w+ }代码展示
0 E) j F3 b# g3 X( |' \. c4 P I3 Y, G
class Solution {; F+ R+ ^: a n' ]7 `4 }) Y5 y
public int minimumDifference(int[] nums) {% c7 Y$ D" |, E8 U" F; @
int half = nums.length / 2;
5 T& J% K( ?5 ~ int[] half1 = Arrays.copyOf(nums, half);
$ g+ ^8 d. B; c2 x int[] half2 = new int[nums.length - half];9 ~/ N0 O2 D- d* |) C% R5 x
System.arraycopy(nums, half, half2, 0, half2.length);: U: @. i; E+ g$ [
// sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序, K- c# k- U2 h
List<List<Integer>> sums1 = getSums(half1);! p9 a5 q7 K! H- G
List<List<Integer>> sums2 = getSums(half2);6 R f# V; t# r' \4 C
int sum = Arrays.stream(nums).sum();! p! z1 z; s1 n3 p- G7 m
int result = 0x3f3f3f3f;; C+ A) P1 u4 R% c" ~% q
// 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个
: a5 p: H# E& e+ f+ r: J for (int select = 0; select <= half; select++) {( ^1 K3 b/ w. ^6 ~9 b% P9 i4 F* e
List<Integer> half1Sums = sums1.get(select);
: _2 d9 _3 D% M) y) g; y List<Integer> half2Sums = sums2.get(half - select);9 I; T) b' Y2 _9 H2 R- X
// 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2' ]. }5 U6 p, b1 M
int i = 0, j = half2Sums.size() - 1;" f# |' M# g4 O. E* b" r
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));9 ]* @6 v4 }( F# g r/ c5 F3 ?
for (; i < half1Sums.size(); i++) {
# b1 o- [4 B! j4 c0 s/ ~ while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {; v6 G; D+ o$ D+ X1 |# @4 M" @4 ~
j--;/ U1 J/ P+ } t3 X. c
}7 \! L# o: P9 z" s8 ^" w+ c. G5 y9 I
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));0 r( x1 y, r) N4 M2 s/ [# A
}
- Y! ~+ d0 z& {9 E6 H }" N: H& N7 S7 ~% @
return result;
, K3 D. c: }9 N2 p }; d& u* N6 N4 u5 b. K# e/ k
4 Y5 _$ f# L, [' N // getSums 求出 nums 的所有子集的和$ Y1 V! X5 g# l! Y) W9 D
// 返回 List<List<Integer>> sums* N$ S( e; m% H g' E
// 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和. a+ P" Y$ r9 g
// 去重并排序
1 c9 h( t% Z! R" X' ? private List<List<Integer>> getSums(int[] nums) {. _1 s/ \$ y/ i- f
int n = nums.length;4 ^% \! T" z' `3 k
List<Set<Integer>> set = new ArrayList<>();" J2 T4 M' |$ J2 W2 T# I4 B
List<List<Integer>> sums = new ArrayList<>();4 z; R5 ?# j' u( @/ F( @) S
for (int i = 0; i <= n; i++) {5 i+ S5 i3 |! W3 y
sums.add(new ArrayList<>());
/ y6 N, f7 o/ j8 w; ?; y set.add(new HashSet<>());
( j5 ?/ L5 n5 a" H1 x! R }
9 W% \1 e+ V- k! o5 B' \7 ^ for (int i = 0; i < (1 << n); i++) {0 t* F c9 \; y# T6 q
int sum = 0;
0 z6 _0 W* L0 n- Z) M int num = 0;
9 ~( F/ q. n! J" U0 S for (int j = 0; j < n; j++) {) H O# L/ E. E, z9 j( r
if ((i & (1 << j)) != 0) {
, e+ {* W( P6 X& u5 Z& D# } sum += nums[j];
; q' v# o- c8 T num++;
' @; O) F H1 Z( x5 o i }0 C/ q7 R2 E9 l% [+ a
}
3 }5 ^% e7 W6 l5 R0 @" _5 I7 b if (!set.get(num).contains(sum)) {
/ G" g( U9 r# S9 m, ^5 ~' e set.get(num).add(sum);$ y) U n5 G# @' J0 i& v: p% U
sums.get(num).add(sum);
+ b9 g/ P" |( u; i! B" F7 {7 c }
6 l6 d" c# x3 o( X- J }% b' L- o; h/ u6 h1 N: ` E7 Y5 E) O
for (int i = 0; i < n; i++) {% M6 {) H; W) B# v9 J
Collections.sort(sums.get(i));; J0 P! g: M1 U
}
* | U+ l N) l; _. ^1 P, d9 i9 B return sums;; d l7 t: m% E' Z3 T( Z7 X
}
$ @' {* o/ @6 V+ P* D2 e} |