登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】' N: K3 c2 W, q# @
7 l/ k% b1 _8 ^" ?: g
解题思路
" Z7 W: a/ w9 A1 P8 [2 z& \4 I6 Q+ _2 q签到题。7 x1 @. r& k" p: F
0 \- B. a/ h5 Z. _
代码展示
m: j+ N$ F$ i! b3 N$ C; x2 p
* S3 l: S* P7 Q6 e. |+ tclass Solution {
+ x6 x+ f6 o) g. Z+ U# r9 l5 k public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {
" s/ c) z( |6 E$ q* K int[] count1 = new int[200];
+ x+ G K7 g1 X int[] count2 = new int[200];
7 G8 A: z7 D8 _8 W int[] count3 = new int[200];
& k+ `; K3 N Z' l for (int n : nums1) {0 i$ d' t/ s W) S" y+ T( C
count1[n] = 1;% t8 ~' F; e6 ~( _* ^" c0 @& x
}- {6 W6 o7 T. D G- m
for (int n : nums2) {. @* G7 ~3 s! j) T& \5 V, F; Q
count2[n] = 1;
4 p. U3 b! U! p- j }- N4 G+ a) c+ K9 u) D3 v
for (int n : nums3) {
% j) H. [+ q+ ^0 G: B y# k count3[n] = 1;& e' P: h+ Z0 r
}
g8 W5 u( E: q/ H( v6 D List<Integer> result = new ArrayList<>();8 Z/ {4 x& ^3 q# e4 i; d
for (int i = 0; i < 200; i++) {: m# g( t# i1 l8 N* \9 k( Z) M$ b
if (count1[i] + count2[i] + count3[i] >= 2) {
! I- S* s) ], L; I/ c" i& ^ result.add(i);1 }4 T$ U+ H: n$ [' y9 w1 t9 n3 ]
}
5 K3 P" f0 z2 Z- g }
2 V7 w) t/ e7 O( z: D8 `5 \6 @( o return result;! V6 v$ }+ B Y0 O4 Z
}5 m. a \/ {* V: W6 f
}+ U* G! G& R7 @
5 x' R/ [) l& B( P `( C5 b' b0 P! P【 NO.2 获取单值网格的最小操作数】$ j# Y) ~; g! P. s: e# v; e
2 W* o! h+ E* }! Y8 `2 }解题思路9 J7 [# H6 X/ s% O+ t
网格可以转换成一维数组,然后排序。
3 g3 n/ N3 D9 Y/ m2 _: I- l6 G8 v$ G1 T" R
不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。
8 ^ T$ J& z% e
- A9 K: h$ ]# c; T; c5 p/ I* o然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。
- O5 n7 ~: `" O. f# m+ \
$ {: K9 S1 E, l& k( D6 I代码展示) D) P6 V" M: [4 k! Q8 f' d+ b
2 g7 H+ B" f; r1 e* qclass Solution {
: k) T. [+ l: X4 @- G, J# Q public int minOperations(int[][] grid, int x) {
9 r. R" t& ^6 J1 Y* ? int[] arr = new int[grid.length * grid[0].length];, f: ^2 o. i X n1 D2 u
for (int i = 0; i < grid.length; i++) {
. Y6 S g' @! C% W for (int j = 0; j < grid[0].length; j++) {
, ?8 q2 @3 P q/ c& Y9 U+ o arr[i * grid[0].length + j] = grid[i][j];" {8 S& N8 g1 a
}
6 {7 x: I, |9 Y6 w6 S6 [; B }4 [, R6 t: d$ k- q3 n- h/ x6 I e9 o
Arrays.sort(arr);' M9 t" h2 G/ \$ @# q0 W
for (int i = 1; i < arr.length; i++) {
( o. t( V/ n, S5 p/ x# Y) S) z if ((arr[i] - arr[i - 1]) % x != 0) {
4 Z# @/ L: v8 ^6 q, o/ ]3 m return -1;& O# E! |, W5 p7 g' g1 W3 E
}5 @. X0 G; W0 I1 P4 Q
}* z b1 a# j5 Y3 b
int suffixSum = Arrays.stream(arr).sum();3 j5 z3 \" A- f" I5 l" k/ e8 R/ E5 f0 O
int prefixSum = 0;
' r9 ?! }" W& k" v int result = suffixSum / x;
8 O5 W! L6 T& v- W# j5 b0 R! l for (int i = 0; i < arr.length; i++) {
/ k; Q+ ?; y) @, e suffixSum -= arr[i];! H; j" k$ W4 O) Y
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));
% s! W0 e* ^' a6 U d8 s prefixSum += arr[i];+ R* s! N" {7 }+ J0 g T
}
8 I) V9 p8 A! n" a8 V9 ^, Z return result;1 w( Y& d3 i o/ P+ N
}1 o4 ~5 M1 j8 q1 l$ @0 m8 P
/ S1 A/ d i2 A4 _! D3 a5 v private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {
& t* b; X3 \) L! B* N. \) j return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;
. o: z" d0 [# Y' t* v( `# ~, D }8 | Q6 K* Z; F4 s2 c8 b1 O
}! k% Z- e: c. u. i! L8 P* ?: S
' }5 t B+ P) T X4 } S+ ^5 c: J
【 NO.3 股票价格波动】+ M0 q! m+ s. O, Y. N" r% E" r) j
& p8 W- X. r7 i# J. T1 X) q
解题思路+ X( ?4 q4 M( [( S
使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。
9 d5 ~) c0 L- C& u, j+ k7 P# K$ L5 j: |4 ? R" W t
代码展示
& X0 `( V3 A# M# ~. Z+ `9 f* D5 \, |
" P7 {2 T& K5 m* T, U# C, O( Iclass StockPrice {
d6 h6 [7 n2 D$ c) d3 q9 G, p- N2 |1 h
TreeMap<Integer, Integer> timestampToPrice;' c( R( T0 m% e; C' b. L
TreeMap<Integer, Integer> priceCount;
, p7 m8 n2 H! e+ O2 [# F8 s/ m$ G9 A H0 x
public StockPrice() {
: _$ l/ x" [* q! q. U timestampToPrice = new TreeMap<>();) w9 y& j* _/ b" H# `
priceCount = new TreeMap<>();4 g! z1 V% n, I c! l: @$ f
}6 t! k/ Z& i! c; T
. u0 K! X) B8 `& U( N
public void update(int timestamp, int price) {
/ o5 V, q9 A6 I1 [+ I if (timestampToPrice.containsKey(timestamp)) {4 ^$ E' U3 D Q) T5 M
int oldPrice = timestampToPrice.get(timestamp);
m9 X( Q* N1 ?0 p" s: v6 p- ] int count = priceCount.get(oldPrice);
. h0 n$ r+ i* {, M! r- T( e if (count == 1) {
+ h7 ?* o" h m4 A+ p9 k3 m priceCount.remove(oldPrice);
- _3 _ G' N5 h+ v" K' {% Y } else {# l2 J2 v/ I# }( ? Z* V: `0 b' K
priceCount.put(oldPrice, count - 1);6 u; J: E& U* Z- H
}' v& L; u! U. Z+ V/ n" s% L) ~
}
+ J- p3 }( h! s% C- V7 j! T' k timestampToPrice.put(timestamp, price);0 ^+ b0 c) x/ `# X" P
priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);
2 @8 k7 O" c' J( Z5 \/ D }! h( W3 a. R4 D: l. O) U/ p
! o1 N* g" s$ a" p' q5 f$ y& L7 h
public int current() {
$ u7 q% Y# E4 f1 I: m) ~ return timestampToPrice.lastEntry().getValue();+ u# [, S( j e8 M/ R+ d+ K/ V; j
}
7 @0 | q! [3 S
0 U* L2 m5 J, G5 Q5 y public int maximum() {2 v$ |9 `4 B- D- Y
return priceCount.lastKey();
2 d2 F. W/ h* g B }! N; Y# y# o, j C8 w
: k- J3 f) ?; O% F5 y' R/ P ^# z
public int minimum() {! @8 R% O, y6 H( f# ]
return priceCount.firstKey();
`9 O! T. q& @ }! W- E. f% L+ \ \! X
}
# P8 u0 ^9 Q6 T( z* l% B# U9 s1 N4 Q1 d$ Z* o, Q& h* H
【 NO.4 将数组分成两个数组并最小化数组和的差】
8 A% ^4 @# H2 {- t' s3 ~+ g8 T3 ^' [, }& y2 X3 q0 K" ?
解题思路
" N' h5 M/ |: H& r
5 j; X& o e5 a$ ^# Z7 Y枚举 + 双指针,具体思路见代码注释。 Y# r' D, o2 F [" c- V9 N
% m" d# d o. ~" P7 Q
代码展示
- L+ A4 w6 Z. f& P6 s5 u! j2 M; J8 w& e+ W$ I1 d# \
class Solution {3 D9 `* K6 F% H, _ E
public int minimumDifference(int[] nums) {
( n7 {" L5 S+ N int half = nums.length / 2; Z6 y/ p1 x! r% n! s8 K% p
int[] half1 = Arrays.copyOf(nums, half);
8 `3 \7 N2 R- {7 n+ M$ f& U int[] half2 = new int[nums.length - half];
2 y2 B! e m# n9 w) b System.arraycopy(nums, half, half2, 0, half2.length);- F. Y+ W' ?* n. b0 Q
// sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序* ^0 h5 Z* O; m( Q$ H0 C( N
List<List<Integer>> sums1 = getSums(half1);
9 e6 S0 _9 ]: e% I6 t6 b List<List<Integer>> sums2 = getSums(half2);
" L. `1 x/ Z9 J- E int sum = Arrays.stream(nums).sum();
; X4 [' o$ U2 m& f int result = 0x3f3f3f3f;) e3 c$ J, p; ]1 k0 c: F7 |
// 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个
+ v E# k/ A+ c. l4 ~ for (int select = 0; select <= half; select++) {
( i6 r' m3 p/ q# A0 C* w- }( E4 t List<Integer> half1Sums = sums1.get(select);
- ^5 U0 }6 Z) h$ D3 N7 M List<Integer> half2Sums = sums2.get(half - select);
# F/ U! @. O: u+ F* A8 m" g# J // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2
6 M9 ?/ S9 `$ G9 m9 }/ B( \( X5 c int i = 0, j = half2Sums.size() - 1;
. ]* e; U' E; J" W3 l0 Q6 k result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));) n* ^- |* N R& |2 G E
for (; i < half1Sums.size(); i++) {3 M0 M3 I4 D: W0 A2 Q Q& V
while (j > 0 && Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j - 1)) * 2) <= Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2)) {3 x: s" O+ `; ~8 r8 n. h
j--;, l4 K8 ] W8 V# ~3 n
}! P, O, ^. F/ T
result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));3 q8 g' e2 y: n% V2 t; ?# c
}8 w: y8 x$ h z5 d
}
* w: ^1 j1 s( q. N' A8 z9 S return result;
* A* [; a6 P0 X& n }0 U. O/ |) ^. W) V( [
" b9 ^: ]: l* u t0 R // getSums 求出 nums 的所有子集的和
5 _ Z0 a4 Z0 V; O2 x; N8 W4 U) U: g // 返回 List<List<Integer>> sums
1 |% m! k0 s+ d6 v! g% x1 b! M // 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和2 U8 D* _5 Y! }9 e# d) a
// 去重并排序
* R- U, L/ B- X* a0 b; @ private List<List<Integer>> getSums(int[] nums) {
9 L; e. o3 m8 @: s/ V( R1 j; X9 c int n = nums.length;0 P+ g+ h9 g R+ J
List<Set<Integer>> set = new ArrayList<>();" ]4 n/ A7 l1 F! k0 ~- |5 R
List<List<Integer>> sums = new ArrayList<>();; P5 T% ~: u: b1 z8 O
for (int i = 0; i <= n; i++) {+ G8 H4 o7 A- M3 b+ k6 N" ^
sums.add(new ArrayList<>());' \- [* U7 W# v# A' _; J
set.add(new HashSet<>());6 |( {. f0 p' e3 N8 G8 L
}
. Q8 G3 @3 J: Z! ^% R$ R for (int i = 0; i < (1 << n); i++) {" @. R1 K+ E& Z1 S$ X" t
int sum = 0; [) z/ ?) o& ~' \1 V
int num = 0;
. r) i6 p+ K1 }: f. v3 F; J for (int j = 0; j < n; j++) {
3 |0 O% u+ j1 u if ((i & (1 << j)) != 0) {
# w5 m9 O) m* E$ u* q, G sum += nums[j];
3 {& S* h7 H0 J, q! [* ~8 ] num++;
$ r* E# N7 O* N# Z2 X; M }: |3 z& Z* O M7 G& g* L: W
}, Q5 G+ U3 }- {' B# i8 D; {4 B
if (!set.get(num).contains(sum)) {! r* O8 W4 v( N, b B; M
set.get(num).add(sum);4 C5 t: }9 _- }5 Z4 e
sums.get(num).add(sum);3 N7 c' k6 P1 ^
}
. V6 ~0 O* L, F2 N/ N3 W }8 f* t! X: I9 a9 w
for (int i = 0; i < n; i++) {1 n; c* p, m/ k2 A$ Q7 B
Collections.sort(sums.get(i));
: R. n+ C2 \2 K. P4 N. s }( K9 ?8 O) Y+ ? H6 U# g
return sums;
2 U9 I0 n( Z% T3 O8 n1 K8 P, ? }+ x; @& H8 \$ Q' A! p1 y. f; y
} |