登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 学生分数的最小差值】2 S4 S( k& | e' z' E
/ a' ~! b- S( v3 t; ?+ f* i# v; C解题思路
$ O- y1 Z# a, F% ]+ p! z& z& `3 b7 X( o+ O
排序,然后枚举每连续的 K 个元素即可。, M& U5 A3 ~1 N3 t; q5 P& O% U
. R" E, `5 V- x, `" i. k( K Y代码展示9 I) `5 ]' w9 Q) p
9 Q; J7 w& S: A) F
class Solution {( B* T9 e! r6 v+ [9 e6 G6 P1 C3 j+ _# ?# q
1 E0 ^- u* B4 a7 y
public int minimumDifference(int[] nums, int k) {% h5 K! s7 i3 w
, R# e8 |0 j- p) s6 Z5 U! v if (nums.length < 2 || k == 1) {2 w! S, b& l1 i! z0 N* M T
" b3 ]. t) r* G B
return 0;; _8 t d- s5 g' `7 C# ?
c; e8 k6 V5 F" g }
0 z7 ~4 B3 n( j* f, v" H
" |2 p" n$ v5 n @ Arrays.sort(nums);
3 R9 l2 r; O3 Y9 D1 b8 j j4 v
8 s, c, |. R' |3 ]; f$ ~0 ]) F" O! b/ F int res = nums[k - 1] - nums[0];
; C' W3 a6 ]" F+ |" {( R0 t: u1 c! F3 U
for (int i = k; i < nums.length; i++) {
1 B3 U9 [( I! u1 k
+ y4 \- X5 `5 } res = Math.min(res, nums[i] - nums[i - k + 1]);) T8 r+ f* k8 D* |: a( ~7 }! @" M
# N# _3 ~; R. I( H: X) g5 {
}
( @& @9 ~2 m* X5 a( W2 b+ f# @. C( r
return res;
8 ^0 c k6 f( O% {6 R$ Z% V- l. Z7 N
}8 |3 P4 M6 h. u/ _& f
: x( S I5 N r2 C}% o o! D" a$ i. w6 `- t/ R
" p5 P1 ^* q' |" o# ~
【 NO.2 找出数组中的第 K 大整数】" q$ J- h" `+ A: n8 u1 X
- g7 y1 r E: |" Y) J解题思路
3 y' T+ h* p: e1 N% h6 i
# R A4 c5 j) K& N按照数值从大到小排序即可。
2 T% q$ b# |: }& @7 b( N5 W* }. C: T' H/ G2 j
代码展示* a! W9 J4 S2 S; k& d) f& T$ V/ G$ u# r
4 y# R+ X0 _. b) Xclass Solution {! y. ~- `" r5 ~1 ?2 Q$ ~
- F; k. r; g/ w, p( J! d, m& m
public String kthLargestNumber(String[] nums, int k) {4 V8 h+ m4 c0 r& \
. s& O% Q; u0 v3 B6 f! | Arrays.sort(nums, (a, b) -> {
6 m% H, O/ X8 |" P; |# d( k
1 T2 [& E! L O" M/ T4 i8 X8 L# z if (a.length() != b.length()) {
& J, E; m5 l3 l/ j4 q- u
?7 K6 E0 X. f7 N# b return b.length() - a.length();- z' d; q9 N( f6 P
8 X+ {7 e& n* }- a8 ~' y. Z" i }+ X! r. E+ c0 t3 { W/ Z! }- s8 A1 Y
2 G& P$ g( Z' a4 v" t* ` for (int i = 0; i < a.length(); i++) {! M" d) x# ^) @9 s- R
/ f' n. {. T& ]. {& J; ~& {& [ if (a.charAt(i) != b.charAt(i)) {
$ C0 K1 p# L; I& {# p% r0 C
1 |! b9 X- b4 U5 G, N: a return b.charAt(i) - a.charAt(i);
9 r& O' ^% Z3 G
4 Z( m0 Y3 E- K- C8 G }
$ k) T, X* o1 g& E) `, p) y! E f; J3 ^5 o' q: b0 B! o3 Q5 m
} S2 W( g: ] Z' N) i
. `$ ~; S; t% D4 K
return 0;
8 c2 X5 p5 ?7 a: }- N9 l5 p7 G" t- t3 n& M2 E( B
});
0 [; ]* h8 [; V z I# q
9 C) ~6 u' v0 g8 A# }. M return nums[k - 1];% V7 |! Y0 I3 R7 o* x8 V
7 |# v3 V, M3 _6 N
}1 A9 I, a! r! \3 O" E+ { y
7 l/ V. g0 U1 e7 z8 v" E
}
; G' C- @+ a) e! G/ O
9 x: _: o& j4 g" ]【 NO.3 完成任务的最少工作时间段】3 e# Y; t* h5 j
. X) Y5 h- q( }6 x5 Q解题思路( c8 F) D, X5 ^* e
# D3 e( }) L6 {状态压缩动态规划,另 dp[i] 表示剩余的任务集合为 i 时,需要的最少工作时间段。
* L- D5 p0 Q+ [1 n1 V7 u, ~4 s
7 Y: \% h p& u6 r: w- r1 u状态转移则是枚举下一个工作时间段做哪些任务,即 dp[i] = min(dp[j]) + 1 其中集合 i 减去集合 j 所代表的任务可以在一个工作时间段内完成。
$ O1 ?' Z2 i7 M9 e; X3 a( a! g% e& ]3 a! t; p' W: |
代码展示' p5 f9 r. j+ x$ J& T
+ p6 ]9 C7 o1 o
class Solution {9 F5 [2 T: ?* p9 e) h0 \+ p' x
" \- W3 |4 Y5 h" Y* \. a, v
public int minSessions(int[] tasks, int sessionTime) {' m" i& k5 m: \
, }4 {; s% E* s3 w6 [
int[] mem = new int[1 << tasks.length];
$ Z* t9 F, Y9 l7 V! `
* Y5 V( _, V* j. L& o: l Arrays.fill(mem, -1); w/ m4 `/ d5 }
! [& ]6 d G9 [, O* M
mem[0] = 0;$ z1 ~* D0 a# n: f1 W
9 s* ]4 s5 a8 {: f6 x r/ u
return dp((1 << tasks.length) - 1, tasks, sessionTime, mem);
/ G1 r: ]' J0 u7 k# m; o- q1 ^6 B' t4 E( g' ?& E+ s. z
}
* C# C# s3 B; G/ {5 x! m0 I, W0 b k8 S8 S* v
private int dp(int i, int[] tasks, int sessionTime, int[] mem) {
' G% Y( u1 G# ]7 o9 O2 u. P3 O4 O) i1 l' A7 r& a5 ?* e
if (mem[i] >= 0) {# j. P$ f: M- x" l5 L; ]
( q0 `# W3 G/ L return mem[i];- _ y* E! u% C5 b- v0 f$ ]+ _9 i
2 h. a* q0 s6 M+ R1 g, P }
E# Y$ H$ u. @5 w0 E* f, F- F8 [
mem[i] = tasks.length;
& H. u9 n2 D# i" L6 T) V+ c3 m. H
// 枚举这一个时间段完成哪些任务, h2 t5 `3 E, }7 @) v! Y! C
3 ~+ A+ O/ N( v- r3 i7 R
for (int j = 1; j < (1 << tasks.length); j++) {
8 U0 ~$ S- B1 b e8 }2 [. @# P9 {1 y
& t b% t/ Q2 G, o if ((i | j) != i) {
/ l- N- @ W6 V3 C5 w$ c
5 y) Z4 A" u/ o% _' p& _5 P& W/ x% F continue; @ M1 ^4 D. m R, P
. Y1 p5 j* J7 U6 E o }
( G" S2 A, M0 O' Y D$ s- R+ g4 I" P/ v$ @5 u: g/ `7 X6 A0 U
int tot = 0;2 d) D4 p, Q( B+ V% o n8 {6 Y. y
5 M. n3 t4 s5 e( e0 x
int ni = i;& w! p3 `7 K4 {0 g0 }
& u, X) g6 t. b0 c* ?$ ?
for (int k = 0; k < tasks.length; k++) {
+ x& s7 L. {5 t( C9 k8 m* k& H! \. Z- [" j
if (((1 << k) & j) > 0) {
/ w* C# @: n e6 M2 k3 Q& T6 O# x( Y) k
tot += tasks[k];
. `1 ]9 h" j/ |& ~9 @+ e0 Z- M A% C9 M' ~: o+ d( _; @; p
ni -= 1 << k;
! K8 m: {( ]# X6 q4 @; e) X2 e6 a2 g3 t
}
* ]: y! {' @8 C4 y# y
) |( R/ g( ?: w/ n/ I4 w% q7 i' B9 ? }' X7 N- b0 O, {* F
3 h2 W# s. D+ z' I& [0 r if (tot <= sessionTime) {
+ D# U( P0 X- ]- {2 Q0 J. c% I6 s% Q' ?5 O1 W; K4 O
mem[i] = Math.min(mem[i], dp(ni, tasks, sessionTime, mem) + 1);0 [2 X5 R( B& O% I' G
: F k+ i F1 k; Z4 s0 T2 @ B
}
2 T- E6 B( Z# O- k& T1 i5 z- @' q t4 s/ h
}/ B3 a; r2 T5 W- l/ R3 L, R
$ h: r2 a* {( M9 R+ G
return mem[i];
; v* J; y* b6 `0 E' j
0 s, Z& X5 l& k6 S" ` }, h, m. Y9 o3 M9 n
7 @; W3 K* ~6 @0 c. Q2 }8 E}" f* v8 |, r2 b0 h& j9 c6 F
0 l7 t' y1 |+ S) r, ^
但是,上面的代码会超时,因此我们增加一个小优化:逆序枚举 j,即优先枚举更大的集合,并且在递归计算前判断,如果一个包含 j 的集合已经被递归过了,则不再进行递归计算 —— 贪心的思想。
8 l- J, b4 Q/ x( c, R. Z3 E
2 Z( Y: [' r% b9 g% q$ I% f( gclass Solution {/ g1 r* t8 X& W% i2 G
0 q7 f2 E0 k' |' k
public int minSessions(int[] tasks, int sessionTime) {
0 V& e" C; C, ]: L% r, q+ X d) {7 V. M
int[] mem = new int[1 << tasks.length];
$ D4 E0 z# J: L
1 X% H D, h% v$ [6 ^2 t Arrays.fill(mem, -1);8 b7 [7 k" _6 {* m# |2 F5 q$ F
8 X! p1 X0 d8 Z. _3 Q& z
mem[0] = 0; H' R% S7 I: C: p2 R& {) D
$ V# p8 W" Q# a1 @0 { return dp((1 << tasks.length) - 1, tasks, sessionTime, mem);# |$ A" }7 m5 T k
& a$ @7 i2 r9 |* W R& ~; C! } } ?2 b* r/ J4 Q2 H8 x
2 R, E: i2 s* f% @* U6 S- N) M
private int dp(int i, int[] tasks, int sessionTime, int[] mem) {- o( Q4 c7 w! m! @: `
- e; q2 H" o6 A; H$ c" H: k if (mem[i] >= 0) {
3 t, Q7 c0 C2 t% B8 E" r+ j
- ] H2 ` c" g% a+ R m return mem[i];1 [0 E( i- D4 y
: ]) ?( a1 A7 H2 j* N# V: V, L5 z
}
, s* h6 p, C. ~; e. a
* x3 N3 e+ l# z1 l& n4 H+ K mem[i] = tasks.length;
; `: ^. v4 h: B+ I$ \( _ T2 X1 |, [# \# J1 s0 |
List<Integer> visited = new ArrayList<>();
* H h+ `$ @, {2 o4 l, J
' ~$ ^, f) D3 d# \1 q for (int j = (1 << tasks.length) - 1; j > 0; j--) {
; y" j$ e ^* J9 o" W; a
& Q9 e- I0 c. D if ((i | j) != i) {
* C F G0 f0 s; h6 A$ a
" x# g7 G% m, |6 E N+ P" G: c9 C continue;
7 g$ C" X" U3 K) }9 p( {
+ c, N/ Y2 q5 P. y3 e! [9 y }
' ^8 B1 k5 D! d! L6 T5 Z) M; o: c" P5 u
boolean skip = false;
, }2 l9 U7 Z. e- P
( _; C0 q) {& k2 N/ s6 y- T for (int v : visited) {8 @+ ~ P# z- i) m+ r: |; F
6 o4 H& i L) ^
if ((v | j) == v) {
9 F' R; r( S7 z1 a+ h+ T5 ^6 \4 m/ S9 [ T8 Z* @+ H f
skip = true;
2 f5 @) v( B7 e' _; r1 {3 p5 F! u3 k) L* O) p D% A. z! p
break;
+ W: L! _ p# ^2 u# p, b4 s& C9 ]# P( K0 S0 i; v
}
( y- `% }) ?7 F; a# R, D( Q0 H! J* V* {4 m, y& [
}; g* [ ~4 b j X) I! K7 V
9 u% H. M8 |) Z* L1 \ if (skip) {
" L4 g. ^! }. u- g( A4 v$ @2 Z# T3 V; J9 U, ]( S4 a( I
continue;
$ G0 n- g9 X; ] j1 B0 }5 a0 Z* V/ a; }) c# O
}/ F1 E# u& B! D9 S
3 w4 o3 g. I; F+ U0 g7 m
int tot = 0;# j/ U: k! M4 M9 Z
1 V2 g J3 {: v# r$ R/ c6 j' n9 y8 n) a
int ni = i;
K$ U& H/ i' m- T/ e7 J+ u8 i1 C# C1 u3 ^' r q
for (int k = 0; k < tasks.length; k++) {8 H4 N0 N+ o% s3 @. V; t& A
! v! |1 `3 P) v; O6 G+ _* X
if (((1 << k) & j) > 0) {
8 a, g: b0 H- l- f
5 P8 i3 k5 V z$ j5 S tot += tasks[k];
+ Z8 O, Q/ N$ N" h
# V: [" G4 v. \6 w( }8 d8 K ni -= 1 << k;1 J- }9 T- \5 t# q: n
, V6 d5 N+ T5 f; b5 k }2 S* w' W& x3 l0 Q0 ~5 C3 T! K
/ x9 \+ z) F5 y. d, u0 |
}9 _, @. ?$ p1 [# S* m5 F+ c' A
) o7 v* p5 `& K, A) c* ~
if (tot <= sessionTime) {) j/ G2 h$ h8 W" `* \( J" |
3 x9 U0 W. c- u3 n
visited.add(j);$ ^& q' J7 h: m+ J8 z
) X; l4 B* x) k# J* p' q- ?8 M; R( J# u: x
mem[i] = Math.min(mem[i], dp(ni, tasks, sessionTime, mem) + 1);6 w: L5 ~. h: m
5 \' z( \- w, A! Y J) J) O }" c( O8 m1 ?. R0 r+ u/ O
- ~$ r* M: y1 I0 x7 m1 I/ h }/ D- S" K* l& D
8 o ~' s3 f' ^" d" Y( [ return mem[i];( G) x. Y& p. E g
0 A, e1 K3 F5 ]- _+ ]. C* {$ L }8 s& j: F) E$ k: d5 {
' x! Q* e2 q) r9 U+ B}, ~4 s$ G7 S0 Y Q ^
$ k, M; T6 U' h$ J: [7 x+ ~
【 NO.4 从子集的和还原数组】
& z( U0 n5 ~7 W5 K* F
0 u- Z8 L! M: {, {+ l解题思路" }+ t3 P, _8 y! v q
7 C; L9 L: l o( S+ J2 f( e! ^这道题目相当于不同的子序列 II 的 follow up
3 n, x, t% ~6 y2 e3 l! U! u/ ]: i; V! I. \0 {7 @: Q) i* w
可以先参考这道题目的官方题解# s2 }9 W l4 o: o, z7 K
1 Q8 A E: p. E0 T
代码展示# |; ^8 S* j" p0 B' W Z3 K
: j: v7 F7 F+ ^% e8 kclass Solution {
& J* L( C/ ~: s$ | ?9 k
1 l* o9 e3 p. w) j1 M public int numberOfUniqueGoodSubsequences(String binary) {1 V/ C; W: Q0 y) f- J) f$ w8 z
$ V4 p4 q: B$ `: q0 d/ ]8 X final long mod = (long) (1e9 + 7);) u# S# |& o2 Q9 L5 G
/ e1 P; ]- S1 \$ V7 w7 G0 |; p5 G long res = 0;
3 w( }$ ~9 ]% \, ]0 J+ J, A# |0 Y! v
& K r' g! W9 U9 h) N/ g long[] last = {0, 0};
' }+ U9 @) o) [1 ]3 p8 e
4 h$ Q5 q( Y: q1 H2 c+ g for (char c : binary.toCharArray()) {6 w0 {+ ^! O7 y5 G3 v# Q, B+ ^0 z! x& f
1 x1 u% c( M( y9 x, E) Q7 N
int i = c - '0';
@8 o b* U3 O; `
5 s' R' S$ x# r. ^3 G7 Z& o/ _ long cur = (res + i - last[i] + mod) % mod;
, w0 U r( ]8 f% \$ d# U& e- j1 x K( _! s9 |
res = (res + cur) % mod;' u i+ c* g" X. v3 Y
+ P+ X9 I- }$ n$ _ last[i] = (last[i] + cur) % mod;
* \# n! F3 P* b1 M2 t' g- b2 ?: l& J! l0 u1 X: O5 n) B: t, `
}. [5 M- C5 J: J) H
* Y: s1 S+ s w a. b! m
if (binary.contains("0")) {; T3 {6 P7 y8 O2 d
1 g) W" l s7 k! l
res = (res + 1) % mod;' R7 m$ v) u% r
R9 C% ^0 _1 E% x3 }/ z% [+ D) ` }# t3 }3 M& a+ \4 y$ d& @* l( z! p
t* h3 z1 J- u. ~ return (int) res;
8 C- c/ v2 r1 v' Z# V8 f0 M" q) V- m8 W4 V% R/ R) v% Z9 L8 K. S) H" s
}
1 ]; a5 z3 I( y7 w5 E! g/ ?# a9 q |' S$ c: z! s
} |