登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 至少在两个数组中出现的值】- o( T: {* c7 ~& d+ _: H7 A2 D7 ?4 s
: _. Q% b5 }+ Z1 @" G$ d% Q解题思路
- F" G* {; ~5 W) T签到题。' Q. M' {. `! X7 w& w9 V# _
; n5 |7 U1 Q, r0 a7 B1 K代码展示, G- j7 k1 L) v
3 z) ~- S, J8 t( c. G
class Solution {
: U3 n; @- g0 K7 h/ ~+ z# I/ S public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {2 _, D9 K6 S" n, V
int[] count1 = new int[200];
# `( j6 p% g) I# V' _3 t9 J int[] count2 = new int[200];
3 k" J; b9 J% D" e2 O+ y int[] count3 = new int[200]; `1 r% d( \ Z% w
for (int n : nums1) {$ \, d3 ?- W* W% t
count1[n] = 1;/ n Z8 B0 j g* c
}/ M6 M) Z q6 x) W7 D
for (int n : nums2) {
! U0 L, v9 s0 h count2[n] = 1;4 `2 T. Y5 ]5 G$ C
}' ]0 r. a6 ]# a! C" I
for (int n : nums3) {
" I% x$ m* U9 z4 s# [ count3[n] = 1;
1 \- }0 [, Z* x t1 ^ }
4 K: U& h: [1 A/ ~ List<Integer> result = new ArrayList<>();3 C* j7 |6 }7 n
for (int i = 0; i < 200; i++) {
" O t! U M3 {8 D if (count1[i] + count2[i] + count3[i] >= 2) {
6 }! _8 |2 ~ z7 p. v result.add(i);; v9 B+ d/ c5 v" f+ S; o
}& Y& S8 V4 T7 F0 o) K
}
. ~4 E. b$ d2 T q8 T* m return result;
3 H' L8 r; l; @. ~& ~ }
+ {2 b2 G0 X; `2 X. n( q} R( b0 M C5 S8 p5 ?3 B
a- ?" I- N3 Q, i9 j【 NO.2 获取单值网格的最小操作数】
: ?/ \) R- I. N; O* W; ?" c8 t- j! S3 Q! [: _0 T
解题思路
$ R$ r) _: s3 O1 S网格可以转换成一维数组,然后排序。- {( T# F( b& \! h ~
" a( d) m( |& Z1 ^3 r, `
不返回 -1 的条件就是:任意两个元素的差都是 x 的整倍数,我们只需要检查相邻元素即可。1 {: b$ D3 ~6 T
: a* w+ w8 Z: |然后枚举最终的唯一值,可以利用前缀、后缀和快速计算出把所有数字变成该值的操作次数。' f$ R$ a; z* ?+ V$ L4 V- E2 K
( H( f, p% D) l: i$ M. C" ~$ `4 _' h! g
代码展示
# t9 U9 |6 s$ B# _
6 C" V% P! B0 O! Wclass Solution {
5 v& g Y) R3 q; P9 B: ^5 f public int minOperations(int[][] grid, int x) {% H0 u! g/ v+ V% P+ j5 Z9 G" n
int[] arr = new int[grid.length * grid[0].length];
: z4 x H* Z8 M, {! ^% w for (int i = 0; i < grid.length; i++) {' [4 E( y% k# e; N( Q. ]
for (int j = 0; j < grid[0].length; j++) {, Y$ O8 }- U9 R$ D6 r8 R0 M
arr[i * grid[0].length + j] = grid[i][j];7 T% K4 v8 A p2 t5 C
}& `/ g4 F2 n- Z" }2 G2 c/ P
}
, S K0 {+ m2 o3 [' l: B Arrays.sort(arr);
5 l* m/ u2 c3 P( a) X+ m0 L for (int i = 1; i < arr.length; i++) {. X, U$ \$ L1 D9 H1 V
if ((arr[i] - arr[i - 1]) % x != 0) {
$ z: H4 }' K N. ~. w$ u return -1;3 z, v6 z' G( B) ]
}
B" Q6 p' `) Q+ y* e }% B6 F. l1 f6 G1 z" t8 l# ?
int suffixSum = Arrays.stream(arr).sum();
/ v6 v. X" a, l' N5 ^1 _6 d int prefixSum = 0;0 t) v) {( a1 F+ @) J! j
int result = suffixSum / x;
$ m- T/ m8 M* y7 D" I* h for (int i = 0; i < arr.length; i++) {7 ^- W1 z; F/ y
suffixSum -= arr[i];3 U8 S- Z9 X' b4 m3 V
result = Math.min(result, calc(prefixSum, suffixSum, i, arr.length - i - 1, arr[i], x));
6 _1 h) ?7 X* V, A! q/ b/ b+ i" _ prefixSum += arr[i];4 }- `" B0 c4 l$ t- E" q
}
7 M# Q4 s( i# c1 u% z6 l$ r return result;9 f% f4 \* f a
}
8 {& Y% e0 `+ c8 d$ h& J+ J8 [% g4 ^
private int calc(int prefixSum, int suffixSum, int prefixNum, int suffixNum, int target, int step) {
2 C& T1 k& X! r9 h9 ]/ a7 s return (prefixNum * target - prefixSum) / step + (suffixSum - suffixNum * target) / step;! w, j* Q; ]6 x, ^ c
}
' H0 S6 P! K5 R! I* g5 {5 _}
6 j4 ?7 ?+ t: r1 n# K% H2 I1 p8 {4 ^* U
【 NO.3 股票价格波动】
+ T- ^; X0 Q2 o' k6 r2 `7 J) s
& O& }; b. V) i n% V }1 L! b1 o解题思路
. j, ? G* z. _使用两个 TreeMap 即可,一个储存时间戳到价格的映射,一个储存价格出现了多少次。, s1 m0 w* V! g. F9 t
D$ q8 u% Y6 v* u0 M9 }
代码展示: l) R- C9 v2 X% r: t( D- n
% t% L% H9 x M E
class StockPrice {" a5 \+ o3 c, l1 O9 ?
% }4 C$ O6 W: s% {$ p' @ TreeMap<Integer, Integer> timestampToPrice;: p% V! ]9 G4 W, X! ~
TreeMap<Integer, Integer> priceCount;
+ E+ {( u; ]; Y
* V9 J, [2 }' @9 r/ w# L) d public StockPrice() {
: d* E: w1 ^$ h timestampToPrice = new TreeMap<>();
: \% l& R8 [5 u7 W' t: f0 { priceCount = new TreeMap<>();6 y, J: w1 m0 t7 p' p. [
}0 D8 @6 ~' V: Y; r
5 w7 T3 s2 ^ K& j* p! x
public void update(int timestamp, int price) {. g+ F0 }! i( j5 |2 ~& g
if (timestampToPrice.containsKey(timestamp)) {- B6 @2 b$ r- p
int oldPrice = timestampToPrice.get(timestamp);1 F/ `8 z& T7 G
int count = priceCount.get(oldPrice);
/ U+ O* C+ q$ j2 B$ r# u if (count == 1) {
" r7 |$ i0 {$ h6 f. _' k: U: C priceCount.remove(oldPrice);
7 N7 J+ h9 Y( a% c: v6 X } else {
0 Z; T5 W* l1 O5 O priceCount.put(oldPrice, count - 1);( s4 Q8 `# n" m
}( o; x5 z( Z; B- @' b
}
1 {3 e; R3 m+ k# L timestampToPrice.put(timestamp, price);4 x6 e5 h2 x" |( E# _
priceCount.put(price, priceCount.getOrDefault(price, 0) + 1);
4 T5 c$ g7 V+ _# v; T0 b: z }
/ K2 u. l2 R% c: A# [9 w1 S9 ]; O9 i3 K$ V
public int current() {* ^5 r& W& B' a" c, k# I
return timestampToPrice.lastEntry().getValue();; M G$ N6 F) u8 s& l# v3 f
}" y( Y; D+ |: l+ m3 ?! l* h
/ c7 d2 U$ m: h' k; A$ D public int maximum() {
5 I0 [# S+ {8 l5 d return priceCount.lastKey();# V5 P$ n6 [+ F& w# O4 _# x2 C
}% h6 } T1 S& F! d9 x8 N
4 k: A: d! r+ }6 S public int minimum() {3 Y( r) s( ~8 E' C
return priceCount.firstKey();+ E$ l& o, }, l+ Q2 l1 x
}
; O0 O3 u& X; A, {6 q}1 S1 U( n8 V8 y d# V3 \; ~
2 a* M2 J; I. N$ c/ B _1 Y, ^【 NO.4 将数组分成两个数组并最小化数组和的差】
& y, ^7 v# n2 j% @/ f+ n1 y2 m% d2 B' N0 b/ m
解题思路
9 l$ m, g4 A+ j! a% J' N7 K3 r" p/ }3 X" M9 Z A j
枚举 + 双指针,具体思路见代码注释。1 p5 b S$ j# ~& W7 Y4 q
# ]) q# N6 ~0 C6 w" K7 t代码展示
4 k/ b) l) v( p- U/ j% W
) y5 O8 R$ D. k; kclass Solution {9 l+ b, o& c( W
public int minimumDifference(int[] nums) {4 J: Q% ~( L; S n" U
int half = nums.length / 2;
; u% H0 _2 C( q$ Y, p, K int[] half1 = Arrays.copyOf(nums, half); y% G. E6 d9 n, Q! T% S* G
int[] half2 = new int[nums.length - half];7 U/ `3 F/ Z5 t* n- j/ T
System.arraycopy(nums, half, half2, 0, half2.length);
2 n8 G$ y& m7 ^) } // sums1[i] 表示从 half1 中选出 i 个数字得到的和的所有情况,并且从小到大排序
0 o+ I/ d3 ~. R# R& G, ^/ w8 P List<List<Integer>> sums1 = getSums(half1);
; M, j" ~6 [, X% c List<List<Integer>> sums2 = getSums(half2);& i# }- X! g' ~8 t( f3 O
int sum = Arrays.stream(nums).sum();
' [: P1 @0 _& ^- ]% B4 z; ] int result = 0x3f3f3f3f;
" y/ ~: d4 Z) B, k7 v/ D // 枚举从 half1 中选出 select 个,则需要从 half2 中选出 half - select 个 b# D& ?2 b* i: e) h: N
for (int select = 0; select <= half; select++) {
8 C- q: r2 Y+ P* Z! [' }. N List<Integer> half1Sums = sums1.get(select);
8 @/ T5 D- ]7 S' J! { List<Integer> half2Sums = sums2.get(half - select);
_7 U& h; N8 U9 }( q' [4 i // 从 half1Sums 和 half2Sums 中各选出一个数字,使得它们的和最接近 sum / 2* {5 ]+ G9 x' `" I! ]4 J+ O+ Y
int i = 0, j = half2Sums.size() - 1;
5 g6 F% V2 t9 \# q# b$ ~ result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));4 R/ l5 J" _) p3 l0 e( D; v
for (; i < half1Sums.size(); i++) {2 U8 c# d& n& 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)) {+ i0 X* C+ a3 p7 v' z+ U6 k
j--;
/ j8 Z, M- P$ Z) V( z; U% \% A' Q k }
& d% P. L% D0 M9 M3 p result = Math.min(result, Math.abs(sum - (half1Sums.get(i) + half2Sums.get(j)) * 2));$ M0 B' T+ b6 B' V( Z
}
' p5 W& {; V: ~" t( Y) t }
& _: `- R3 d. I- |" R6 Y) V return result;; C! E5 n R$ x- ^8 z- [
}4 r( ~1 w8 G% @; f( o! F
5 }9 [& s$ r- k6 |
// getSums 求出 nums 的所有子集的和
' e8 C7 `* b2 e2 }/ i, a // 返回 List<List<Integer>> sums y# `1 r& I9 H' a: I! n' H
// 其中 sums[i] 表示 nums 的所有大小为 i 的子集的和
5 V9 T! k# }7 J9 U1 z // 去重并排序: ?7 H; h4 F) {% t% C
private List<List<Integer>> getSums(int[] nums) {
5 p* h0 F+ J i# d1 c int n = nums.length;6 q+ l1 n2 L5 o% R% n7 v0 Y% t( M
List<Set<Integer>> set = new ArrayList<>();
: b; P: R5 Y; r( [$ h; p List<List<Integer>> sums = new ArrayList<>();, L* D: T' i3 b4 O+ E% R
for (int i = 0; i <= n; i++) {7 s* m4 l! I! _# J
sums.add(new ArrayList<>());
8 z0 h# S0 a2 ?7 t1 ? set.add(new HashSet<>());3 x9 d: @- z! t
}
6 J; g" H2 \4 B7 Q; w for (int i = 0; i < (1 << n); i++) {
/ W; m4 n* p( X2 | int sum = 0;) {* Y- Z; r7 X! [
int num = 0;! b) n* l, h B0 U1 q, Z
for (int j = 0; j < n; j++) {
4 {! S: p( g% w( H& S$ d! |2 _- r if ((i & (1 << j)) != 0) {
5 q# x: N t1 n2 C8 G' ] sum += nums[j];; }: [6 Y, H( q5 j3 A" d
num++;
# @, ?8 ?2 C, F! u2 j$ Z" u }& o( W9 _# P3 M( U5 b8 y4 e" l
}0 x4 v# m# {* L3 Z, m
if (!set.get(num).contains(sum)) {
5 a0 r. }& I( t" ? set.get(num).add(sum);7 B: k, |8 }: O: q: C9 J! K
sums.get(num).add(sum);
3 W1 H! S. i7 p, V$ l }
- Y5 X+ i' e- C8 I }/ k3 |- k8 K( D- O8 _9 G
for (int i = 0; i < n; i++) {
# F6 D; F0 }9 g Collections.sort(sums.get(i));
! N8 k* x( Z0 q7 T }; z0 k; C6 x7 i% K- p4 P7 Y
return sums;* g5 e# w- u. f( k. ?) o7 A' H
}
. Q' `( K, T- m& Z' }& }7 P" n} |