登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 统计数组中峰和谷的数量】# O% M: C: Z) }. ?4 K. [2 e% H
# |: m! v' F+ S0 I4 e解题思路
9 n& R( ]8 V8 @) U1 N先去重,再统计。
; F8 {0 m" `% o, z% ^1 D+ T) \$ W9 W& ~; l0 R
代码展示& ]" {. c- i; ~ n; y7 o
; S! ~2 l# S5 i* V/ m7 g2 ~2 n- Uclass Solution {; b0 _+ x2 x* M$ B+ U+ j- e
public int countHillValley(int[] nums) {
) G( k& x. @8 \# j int len = 1;, B4 F8 u/ S& P9 u* ?; p
for (int i = 1; i < nums.length; i++) {
4 v5 l! p! s2 U8 n, D7 D. e if (nums[i] != nums[len - 1]) {' l2 X9 G' G+ `( Z. ]+ y; U
nums[len] = nums[i];
0 B0 U' \1 Y. W7 E4 j6 |' p len++;6 c4 c7 w0 |) I! I9 o* o$ n( M
}' d4 ^$ D) ^1 g8 u5 J
}
; d4 h, p$ _8 f1 Z5 _ int res = 0;" |* w' ]9 M+ T# Q( z
for (int i = 1; i < len - 1; i++) {/ u+ }' B$ X4 |4 p- I$ Z
if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {- O4 I; P$ v6 X( ^+ B
res++;2 A2 |/ A3 b- v& [
}1 W6 {. m p% p' W+ E$ }, u% ^
}
k- h+ U) Z6 Z0 g- B/ y return res;# M( @1 Y5 a9 H9 W& Y& ]4 i
}
% p: j/ o, H7 O( N$ o}
# `8 R: m) c' C9 V
8 A1 l2 r4 `! [, D- P, i( M
# s" s: f: E* }2 s& G% Y【 NO.2 统计道路上的碰撞次数】4 g% \2 B8 D) T
0 {' Y$ w U; Q' _解题思路9 X. c# P \* T( d I- ^
从左到右遍历,维护左侧的车的状态,有两种:" }, D% s6 J/ [4 M9 [7 @
, V) \% k; J _# }+ [2 r若干个向右行驶的% T5 L$ J$ x+ Z: H/ m1 v: i
1 r4 n0 L$ U; c停止
1 K# i- ?9 p( t0 R8 L0 J$ A
4 y; |2 d) }6 m& u# |; D6 f代码展示6 |8 w$ w' j8 V h1 H/ K! M
u" `$ k+ ^- {. O8 g
class Solution {; \5 @5 w* y4 d7 W
public int countCollisions(String directions) {+ `& e, _) u% i+ s# k8 H( [5 G, g
int res = 0;' L( y" K" Y2 P% ^2 D% O H8 }
int S = 0, R = 0;8 ]6 D' M Y+ |; P, y
for (char c : directions.toCharArray()) {" o; |- f' g! I+ i4 y: x& H
if (c == 'L') {# K$ N& Z* W; ~+ P) S4 w; l
if (S + R == 0) {
5 V% x$ {0 L: v. V$ Q1 K2 C' l continue;% X) M7 f5 g( L# M: B$ c; _
}( Y/ g1 O, A6 [( v2 F. @
if (R > 0) {
' o. p2 k4 X+ ^9 y: [" c5 d res += R + 1;
3 `/ ]! h# O6 D; K+ h2 k S } else {' v% t5 i$ v1 Q7 S
res += S;
1 c* X& u: C/ A* S, D }
4 ?( y* N* O% X# x S = 1;5 ~1 |9 `, k8 [5 _9 k# D! Z
R = 0;
, Y4 F; l# y0 b" Z y }
3 m, W2 D' K# L" [/ |' e if (c == 'R') {! K) O2 t, E$ P0 F
S = 0;5 Q v _+ |5 c% Z3 c# d1 {; c) J/ o
R++;) {* |/ O, ]( o+ d/ o7 `% h
}
. B: C5 ?/ |5 E. A, A; J if (c == 'S') {0 S0 T( F, W, K4 v# e
res += R; c1 H3 f2 t* G) _; I6 y6 i! T7 h
S = 1;
x8 ?: [) v! Q0 V R = 0;( N( u6 A+ {& }1 K3 d
}
7 A& Y: o6 w4 P5 z {; w: ^ }, @) g4 w. N. i) x
return res;4 J' h5 T" Z& S, [
}
4 T1 f4 Z/ M6 o* o. c}4 q% X4 z9 P9 [0 Z1 `- U1 t
. ?' M4 v% b) h% u1 P: t8 E) Z2 k5 K- t W; i
【 NO.3 射箭比赛中的最大得分】( u9 _* p) f/ f% i- n3 o
! s5 f1 A* K! m$ o7 M' k
解题思路0 \, |; D6 J/ q7 a) N5 o! \
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
! h$ m, V. T' F i
: \- b+ K" U/ `& ^! x( ]贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。) Y3 q2 _+ H% p: D2 ?; _
2 `4 L7 h4 Q" S; E4 h# G9 r
最后多余的箭可以放到位置 0.% j8 `' @# ~* a' {* v7 }9 {7 ~
; i1 p0 x) ]8 K( l! p$ a: t3 n! J代码展示
4 t2 V/ g% n* l. {# }# j8 l: H
/ o2 d8 K6 O4 b3 v2 Nclass Solution {0 O- K' D N. q4 H3 [8 {7 x
public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {
* I8 G: P5 [" X int max = 0;
1 L, ]1 v% [; h' @ int[] res = new int[12];
/ O( ^2 y: ^' P0 j) r for (int i = 0; i < (1 << 11); i++) {+ {! F- `* u( D4 U& J! _
int num = 0;4 c8 E! N( s3 A# ~7 O/ q1 z3 v
int score = 0;
1 Z4 o( K `1 @% c8 F/ t for (int j = 0; j < 11; j++) {0 [; v, s9 s* y0 U: M- w
if ((i & (1 << j)) > 0) {: W( A1 b- {& I; x6 }9 E9 b
num += aliceArrows[j + 1] + 1;
# ?' o7 M5 l/ i3 w6 ~5 E score += j + 1;
; V+ T! m! U+ ^; Z9 b7 ] }
1 O2 j4 n8 q: S( ^* I+ b; S }
: ?4 {$ f1 w- I if (num > numArrows) {% O% Z( c \. R
continue;
* D% r% z0 F3 r$ h: \( h }
& D5 }/ P0 Y0 L o if (max < score) {
- x g. j, R/ W3 Y& R max = score;! f4 n; | i& C8 e
res[0] = numArrows - num; // 多余的箭8 ]5 n5 R/ w0 k
for (int j = 0; j < 11; j++) {
- }4 b. k" ]: `. E3 _! D! E if ((i & (1 << j)) > 0) {8 Z. U8 X( m i4 R* t& D" X
res[j + 1] = aliceArrows[j + 1] + 1;+ b) H6 s# ]+ o4 j% {
} else {
# P# O/ k: Q+ d0 b7 |' | res[j + 1] = 0;
" ^2 g! n7 k9 j' e; x# R7 f$ X9 q1 i }8 m: b' u5 T( T5 H' z
}
& N4 f6 N6 o7 _- W( l% ^4 D4 A# y }
. ^% m0 {0 _/ I1 M3 N }$ J9 f5 |; b8 V! w. a- X j
return res;$ ~: p+ W! n& _2 r4 N
}* g! A9 Q! ~/ r3 B( Z% P/ d
}1 Z( W& F' _: u3 }, A0 g
x1 ~& t9 t# m% @
8 `; ]4 O) r2 ^
【 NO.4 由单个字符重复的最长子字符串】
5 }7 z8 e' g8 f. L, u4 Y* w6 G. C. k1 T3 x6 G" j
解题思路# w) K% J& a2 n3 G0 V: h0 v
灵活运用 TreeSet 即可,详见注释。4 h- W0 L3 ?( M% {
+ p; [. Y2 J1 u" v- }# r0 v代码展示
* M* ^+ N1 N' T; P* M7 ?; i2 t
+ J4 P% M/ [6 k; P0 ?6 ]5 W2 W% m6 gclass Solution {
2 g+ a# G, {! a U- n6 r
' @0 `% y3 E9 l- k1 t // 一个 Interval 表示一段连续的字符
+ F5 v7 K* F9 M, r' w( P static class Interval implements Comparable<Interval> {
. g2 u' ]- O% q! { int start;9 c* a R6 d" M* m: U
int len;+ J2 c( A% K: R/ Y+ b; x
char c;
/ b9 |2 x; q2 B% J) D8 u9 s+ v7 {. I
public Interval(int start, int len, char c) {3 [! n* R6 G9 B6 G1 Y
this.start = start;! n( p4 C' R; ~2 P
this.len = len;, R3 F6 E! c/ A; O" j8 y6 N$ K- r
this.c = c;
5 S; s+ a7 x: o, ?! F }
( I' D& x5 m1 r) h4 ^$ ?2 t9 W H& T7 D+ b* R5 D# v
@Override
j$ D. ]* E3 v5 w( ~( c public int compareTo(Interval o) {5 o, |1 @6 o2 o# ^. A- ^
if (len != o.len) {
/ u1 v9 y" J- @! G( q H return len - o.len;
6 b, H& ]$ T% J/ u }! ^; J8 D% w% ^3 V! y
if (start != o.start) {! I5 N0 n4 f/ m; m9 m/ z v% w
return start - o.start;' y9 c3 Y" O) q' ~ G( ^" t0 \# j. z
}
, O T, x& B# x) l/ T$ @ return c - o.c;. j" x* L" P) W: |2 r$ S& ^ Q
}, V* M% }: z7 [% u G" d
}
0 W5 `# `: d; Z N$ e8 H
6 V% ~; t5 E' m3 J8 P4 |4 u; R public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
0 u. q: ]6 e4 P/ k, w // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理! R0 w8 l- n6 _4 X' w9 S, A; |
s = "_" + s + "_";
" h, A- a' j. L5 B) D // allIntervals 按照 len 排序全部的区间
' _" @7 {, Y9 S1 g% u; T* D. q1 H TreeSet<Interval> allIntervals = new TreeSet<>();- h. P( a- ^! M9 v: r
// intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序
! l) x6 n* V, _& b, U Map<Character, TreeSet<Interval>> intervals = new HashMap<>();: [4 Y1 l8 ^% G7 L7 c
for (char c = 'a'; c <= 'z'; c++) {
4 T: s2 u/ T+ J( d1 z$ Y4 Z. x0 { intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));
( O. X, X+ I% j1 m9 ^ }
5 ^, c# _1 r9 A L+ M# j intervals.put('_', new TreeSet<>());
& A) E/ z5 O- H3 J8 r$ P4 W y5 V" t1 l; ?0 o
// 遍历 s 维护 intervals 和 allIntervals
: |2 m9 I" p: q! j+ T; G# ?% ~) v6 b, I int last = 0;; j0 R# @1 B- |1 e- L8 a& k2 E% G) ]) k' E
for (int i = 1; i < s.length(); i++) {6 [4 ] i+ z% p9 P+ i
if (s.charAt(i) == s.charAt(last)) {
5 k$ w" K/ K! T: Q( b7 V. w8 s continue;2 g& ?) I t- o/ E' E3 C
}
' d9 ^8 |& j& V5 H4 z$ v. J Interval interval = new Interval(last, i - last, s.charAt(last));
* {3 M) F) s, z) K9 N3 f _# T0 e allIntervals.add(interval);
1 `+ f2 P4 t, n: l9 U! o. B intervals.get(s.charAt(last)).add(interval);
' P1 K2 F5 x& h0 Z6 p6 H last = i;6 s. K1 ]# a+ [6 G5 r) X, r S9 E
}
5 G* z6 |9 U5 _, e Interval interval = new Interval(last, s.length() - last, s.charAt(last));
: Q( P8 f& z& W1 I2 N6 L+ _ allIntervals.add(interval);# S9 y/ t8 N; S) e X
intervals.get(s.charAt(last)).add(interval);
8 F2 N' y2 W/ ]/ q( @, G. B0 I+ H5 X1 {5 e( ~
// 每次 query 调用 maintain 维护 intervals 和 allIntervals* j7 S9 _5 N/ O5 m' F6 \
int[] res = new int[queryIndices.length];* y) y: W$ k! v1 F) N; O
char[] arr = s.toCharArray();
- k9 b: E1 T+ {9 \) Z5 `8 Y% | for (int i = 0; i < queryIndices.length; i++) {
, w( \( G3 n7 u! M; ^/ h res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));
# Z. S; x8 g$ [" m, l1 ?: G0 ^. E }' ~! {+ ] h [
return res;* `; M$ m8 u" L3 z& [+ w. \6 F
}( G; x9 E5 C6 p% l$ T _+ G) E- M& ^1 ^
* O+ ?. J5 e- E6 T k; F9 }- k // 将 arr[idx] 替换为 c
/ r9 g* Q Y. Z0 B. o // 维护 allIntervals 和 intervals" C3 Q) v2 S6 C& l9 j
// 返回单个字符的最长的子字符串长度
0 f0 [. T* Y/ P private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {; l7 L, U% n$ M; l
if (arr[idx] == c) {
3 ]/ G% |, C! q$ l: S return allIntervals.last().len;& K1 j5 K G( a* o3 g
}
7 X4 v* a3 r1 _( ?2 G1 l" e/ i* W' N/ c6 |% e% B. {
// 维护原字符 arr[idx] 的 interval
0 u* T/ Y; E' e* h var treeSet = intervals.get(arr[idx]);
" ^/ ~7 U4 \7 A7 p$ {6 B! g Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可
4 V/ |6 y) v! c/ ?; E7 k treeSet.remove(origin);
/ X* u# f2 }- Z, C8 O allIntervals.remove(origin);
+ U0 u5 |; G' Y7 o4 E7 @ if (origin.start < idx) {9 V9 e1 z2 }! t6 J$ ~! T2 U) I/ q
Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
V" \, ]7 M. \5 M5 ^3 H treeSet.add(interval);& F5 |- M9 |2 X8 i
allIntervals.add(interval);6 T% V/ K2 D# Z
}4 U5 S5 A- V/ K l+ e" `6 ^: e! d) `
if (idx + 1 < origin.start + origin.len) {
2 K7 u1 n4 x" A5 v$ h Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);( C" r7 ?" Q% i4 X
treeSet.add(interval);# G4 w8 T2 u( z
allIntervals.add(interval);
3 h$ m# f$ C: v }+ \% N5 r3 A' g0 i3 ~5 M
8 ]3 m, z; j6 D4 e8 y' e
// 维护新字符 c 的 interval
4 W7 g$ P8 z$ \$ g5 i treeSet = intervals.get(c);4 I' J$ V) L4 @# C1 x- B7 |( _
if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接* ?! c `' ?! R5 m6 ]/ h# y: Z, T6 a
Interval left = treeSet.floor(new Interval(idx - 1, 0, c));- E0 X8 Z+ C8 ]2 V) E) i- R
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));) x! L" @. ]9 |8 Y- I
treeSet.remove(left);4 P0 e' r' G1 P: b0 g2 @
treeSet.remove(right);* T' g. W2 [) ]7 l/ S
allIntervals.remove(left);7 U/ D5 `' b; L3 @2 d# q, {6 W
allIntervals.remove(right);
6 c0 x* z% u4 z6 K2 m) H Interval interval = new Interval(left.start, left.len + right.len + 1, c);
: ~ @5 }' P8 V2 C. Y5 q9 E treeSet.add(interval);5 m3 R0 e# {% c; o+ ~- P
allIntervals.add(interval);
0 g# l9 p8 l2 }, M; G, f } else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接
2 e: K) G! G5 i+ k) o1 U1 v Interval left = treeSet.floor(new Interval(idx - 1, 0, c));. N! K$ K K9 I1 g
treeSet.remove(left);, R# q! Q) z2 b/ ]
allIntervals.remove(left);
( I7 Z0 Y/ I. o1 ` Interval interval = new Interval(left.start, left.len + 1, c);
; |$ D1 [2 Z1 G' {8 Y/ ^* E4 Z% T treeSet.add(interval);( G+ D" c w" Q3 P0 ?( T
allIntervals.add(interval);
% O: G8 ^7 |0 |2 X/ W' c } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接8 e) _5 `- I& V# d$ e
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));( E( @. u+ Q7 O
treeSet.remove(right);
$ G w7 B$ T5 p9 `) C allIntervals.remove(right);
8 K% e7 x- i; L+ O+ }" h; V' c Interval interval = new Interval(idx, right.len + 1, c);( k2 t2 N9 y4 K
treeSet.add(interval);3 ?3 B+ C% Q* }. i6 N
allIntervals.add(interval);4 c _ q) b f: W
} else { // 单独一个/ W; u2 ]1 ]: Y" a
Interval interval = new Interval(idx, 1, c);1 u8 w3 E( a! D
treeSet.add(interval);
3 L6 {3 e! |$ V) H( ^ allIntervals.add(interval);/ P0 T/ q" ^& k; @ |8 \. O
}
9 Z5 I! D2 R2 J6 y; o0 ]+ g! X5 J' h5 i/ G* y
arr[idx] = c;* F, a' v% A* I6 N1 `
return allIntervals.last().len;3 C6 r9 Q6 e% b
}. c) ]* j; T0 R5 N' Z' J
} |