登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 统计数组中峰和谷的数量】
/ r6 h7 z) R- A" ?; M) B. g! s! k
" P/ R5 u9 v/ r0 g解题思路
! Z* W I$ Q; F9 m) G1 C先去重,再统计。
* s2 t% [; }! y9 i2 ]/ Y; m0 A# a, L+ S. o" M3 e S. [# L
代码展示" j0 e$ k( N0 _; b2 a
8 `4 T' _9 j; n6 T( W% Xclass Solution {8 i/ y/ I$ I: w5 U- w; p. @; \6 Y0 |
public int countHillValley(int[] nums) {
) D v( }- V) l$ G3 v int len = 1;
/ M/ Y c3 D2 p: [5 v for (int i = 1; i < nums.length; i++) {% N+ z+ u! H+ F' }1 r/ [/ c
if (nums[i] != nums[len - 1]) {
9 o4 C% \& z/ P; ]& y9 r! L nums[len] = nums[i];+ a6 h0 e4 F" o" l% K( @/ ~
len++;
, u a7 A( M- w- h }% O1 O' x5 e# q7 @' v
}5 J. }7 F# X% `' H
int res = 0;
. D% I' ^( _! z for (int i = 1; i < len - 1; i++) {4 ]& |! v- x! {+ |
if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {6 {2 D; j. m" z5 S
res++;
( \( p2 }- _( K9 S. ~8 Z }
# e0 u+ e% n1 {" S2 W) w3 B# W }$ N1 R1 V/ v" L" s
return res;
9 }6 P( R3 ]7 u9 D' h7 C }
) z$ u8 ^+ L* c1 z( i! d) k}
3 X+ o8 Y$ V0 {
! h) M: a0 [5 D5 W6 c
; A' Y( _/ K! W, w* Z# J& j# K# H1 S【 NO.2 统计道路上的碰撞次数】
+ j7 }& P& m5 @* y0 O
$ w, t# j" H$ K( _8 y" R解题思路0 C5 D. d- l0 a3 _
从左到右遍历,维护左侧的车的状态,有两种:
+ J6 r2 N) e4 {0 q4 y5 R3 D& M% v& H) r/ l- r( m6 \
若干个向右行驶的1 f* A6 I- |3 M9 q: M
' |. o' F4 v2 N6 z7 o$ [, K6 l停止: s3 N$ m; Y1 u+ I+ {) Q- v0 Y# W& n
6 U" z- O# |9 e ^5 ?
代码展示
! v& i/ z v9 q
o8 j- a8 E, @- b& Eclass Solution {$ y* _- C" Y: o }+ S7 t
public int countCollisions(String directions) {
9 \$ `* ^/ m }3 p! a4 K3 { int res = 0;
0 c P; g% Z" _( }) Y, d int S = 0, R = 0;8 V' \& e8 S" d7 C1 S% {2 n" h
for (char c : directions.toCharArray()) {
. [* B; E/ K) P# {/ M8 E if (c == 'L') {
- Y: N1 y+ v* v if (S + R == 0) {
, d8 w# w# e' Z. E. \4 a4 u; n3 k; O continue;
0 Z1 Q0 @- v; W6 Y. t- u6 u } @, @; E! B) W* F6 Q0 e
if (R > 0) {+ u0 B' L+ o) a9 V- q$ z9 Z
res += R + 1;
( [4 y6 V% q" o7 c } else {
2 `1 G0 i% A( I res += S;
d1 P) _* ~& U) k! E% o, `. Z }
, L5 u* \, h) C7 Y$ E% ? S = 1;. n! g4 n9 ?. I7 s1 y' T9 r) ?
R = 0;
/ P( }5 U* `6 { }8 E! `! F- ^* l- X$ X
if (c == 'R') {9 V [2 z: @; U% y. W& y% J
S = 0;6 r0 v+ `1 Y: t M+ \; B
R++;9 ~, l, [& b4 ~: R" x# p! v1 I
}
) C: p% V6 V& j; Y- | if (c == 'S') {
7 ]6 m, C6 O$ `- v, x5 Z res += R;
6 ^# |: e2 h1 d3 ]4 u# |2 c) t S = 1;
1 Z; q L( H0 P# x R = 0;
" Z' L* E, j F% d( W' ^* P }$ w7 n+ v+ h! b; ] k( |1 B
}
' e6 v( C3 g. O1 T return res;$ [+ e3 s; M& [* }* Z+ `' z6 r% N+ `) }& ?
}
5 P1 R( h) v* u; N" i. v}. }: z% \# e# N. P |+ }* j
/ D! e+ }1 y8 m! j6 |5 W' R/ I( l% I
【 NO.3 射箭比赛中的最大得分】8 T- v# _& z: j- b' l0 {
3 ~2 f, \' t5 D+ V
解题思路
+ n" w7 m& W' P4 K枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。. D2 @+ _3 s% E9 ^0 C1 K" r2 [
+ c+ O2 @ Q" V贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
, P/ h5 e* \$ q: M2 g Q1 M% [$ O' F
最后多余的箭可以放到位置 0.
& Y" x, G% g! ^# ~8 x& e
# S4 f4 |: q$ _7 l# D- i1 m代码展示9 y# q5 z' p/ U
: b" A/ ]* d3 I( i5 w( tclass Solution {
" \; Y- J4 V8 D7 d public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {* ~" {- I& E1 ~" I
int max = 0;, Q- T2 G" S' Z
int[] res = new int[12];
9 l' U3 V' ~, e, I" f* e7 p! J for (int i = 0; i < (1 << 11); i++) {
/ M% ?- L: [. z2 E7 Q int num = 0;
; d& R, I' V, v8 Q) _/ s- b int score = 0;
]$ I% g/ y( d, X4 u for (int j = 0; j < 11; j++) {- j' W: ^1 I* S5 L `
if ((i & (1 << j)) > 0) {
$ D6 x9 v0 n- [7 q% Z7 T; _) { num += aliceArrows[j + 1] + 1;
* c5 R4 J" b& D; @! I8 O1 [' O- z( r score += j + 1;, r4 x- _! F: i+ ~
}
8 T+ \+ Q( q) d" `( o+ ~ }
" Y' ^: @0 a+ V! u' d if (num > numArrows) {, h: C( X/ L7 ~' @- a3 j* o1 ?
continue;* a1 P$ ~' X* {$ S* N, W
}8 |* A+ ~ D8 |1 r4 H' j* ^
if (max < score) {
8 h; v9 w# \" \9 A/ l max = score;2 Q* @9 }0 Y5 V w5 @8 |8 z0 X
res[0] = numArrows - num; // 多余的箭
$ p& D( F/ w- A! k for (int j = 0; j < 11; j++) {2 ?( R9 o% K# j. ^
if ((i & (1 << j)) > 0) {
! H7 ]/ u5 v1 @5 O9 k) ]4 J res[j + 1] = aliceArrows[j + 1] + 1;
* V7 h. M- y/ _3 [5 v5 z M } else {
% d* q& L' w1 V& ] res[j + 1] = 0;5 e, C+ ]* P( R% S, D# X
}
. ]8 N$ c, {6 B0 P }+ ]: O# L2 R: i
}
; W3 W2 o: k9 c: P% K; ~ }) L U' u; O4 t1 |" A7 Y4 m
return res;( e+ v& \. h$ q8 I
}
- W9 g U. W* _# A7 v}, ^7 }* i. y0 k4 E2 V1 `1 e5 f( f% |
) B/ Y: z6 A& G* ~
2 b' g) ^2 K0 ]8 i【 NO.4 由单个字符重复的最长子字符串】8 c/ ?/ I: ], C) V1 v1 y
5 q9 T" W0 I: k* d9 q解题思路
/ H9 I" h' z! u& J灵活运用 TreeSet 即可,详见注释。
' B( r& C! k; r0 A, p7 F- [: C3 b8 n& {% o
代码展示/ d5 s M) M4 H4 b3 h, q
5 a; |" V3 {. T2 P; b- H1 ]) P
class Solution {. Q/ H b0 P! {0 z0 l$ m2 O2 m
; H% z. F8 Q" K // 一个 Interval 表示一段连续的字符
& P( l7 G9 s0 a) h6 } static class Interval implements Comparable<Interval> {8 P7 p' L& @) c" J' O( |3 J
int start;( K& k5 R) a6 R3 q% K- y" J1 W
int len;9 D1 q3 C$ J1 D* d# M: f9 a
char c;5 y; f3 k& A# U3 W
( S) k6 Y! w6 h. F0 }, `( j
public Interval(int start, int len, char c) {
5 K( i# q# z; _& i5 f X9 Z this.start = start;
7 L- V+ m8 A7 A2 p4 x8 {" z this.len = len;
7 }# ^# W5 p* U5 P2 y this.c = c;4 H! Q1 N( n1 Q/ e1 G; }4 v5 x
}
$ s( E7 V5 l- u2 ?% d1 N5 s* p
3 h- D, T( A* K, B b8 l @Override
" l( ~+ D. j1 e# K4 X, N& f# q3 _ public int compareTo(Interval o) {' P' B- U3 T. k+ t
if (len != o.len) { Z' ^0 \! i# @, R
return len - o.len;; j7 B( R6 |2 Z) a7 t# [
}4 J5 {4 Z) Q* w: [1 i
if (start != o.start) {
r- M5 x1 |' b return start - o.start;
- l2 l2 X$ e' c9 c( @! c }- Z$ L% j( B$ P# R i4 y
return c - o.c;* P$ M4 b/ ~# _) K9 t" I
}! R, g1 |2 g' v1 ?+ }
}! o6 g/ R0 y W y Z8 n
* U$ l; Z% m0 B# I$ h1 r3 U. x- s public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {$ I8 `; W9 j; d" N
// 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理
" e5 ]6 v$ d# f" ]9 \& E s = "_" + s + "_";" q* i$ v" m- _. U% M$ U' d
// allIntervals 按照 len 排序全部的区间
% ?! D% C! g' [. h' \8 o TreeSet<Interval> allIntervals = new TreeSet<>();
/ {! H+ L/ ^; j) R" z // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序! }) h" v! x d* U5 p1 o/ H% ~
Map<Character, TreeSet<Interval>> intervals = new HashMap<>();) X4 d$ |* P% V9 K
for (char c = 'a'; c <= 'z'; c++) {: n1 h& {7 i' s% l; z0 X
intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));
% f$ } }9 z( A! ^ l7 n& c }: K- y4 m1 B5 O$ v% c8 C; ~
intervals.put('_', new TreeSet<>());) E8 U# B9 E$ ?0 K+ t
% S1 D2 b& L0 E. V# ~' L! k
// 遍历 s 维护 intervals 和 allIntervals% b$ f- i0 w4 p7 F
int last = 0;
$ n% J& t: ` G+ w, s for (int i = 1; i < s.length(); i++) {
8 k" B, T) d5 ]( _+ d if (s.charAt(i) == s.charAt(last)) {
0 W7 y% b% @2 f& A3 p' c continue;
4 L# F0 v$ u6 a9 Y6 q }& w- \! y2 X( _' x- G
Interval interval = new Interval(last, i - last, s.charAt(last));& e7 T: z8 W C3 A
allIntervals.add(interval);$ w. V5 h5 B: r0 }( a
intervals.get(s.charAt(last)).add(interval);' N& v; x3 P( v" o' e8 K
last = i;
4 B# |) `9 K+ N; |) u }
, f# U$ K* f6 B# I) [ Interval interval = new Interval(last, s.length() - last, s.charAt(last));
- T: i" Z* P; S) _ allIntervals.add(interval);" }2 e# K; @# Y5 b/ q5 E
intervals.get(s.charAt(last)).add(interval);( l% L" A+ v' d5 U
1 l4 V, N) t, Y // 每次 query 调用 maintain 维护 intervals 和 allIntervals
. S( a, D! q# [. g1 h. {& I, _ int[] res = new int[queryIndices.length];
5 F" |$ A5 |+ @$ S1 o char[] arr = s.toCharArray();& p* p: e9 V1 E7 e4 l% g$ V7 M& H
for (int i = 0; i < queryIndices.length; i++) {' [; Y& @1 H q& n0 ^1 K7 m& `
res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));3 S8 a) z5 p1 w' o5 `+ R
}* A( q/ P# d# e) s& M+ }4 W
return res;( i/ D+ R. Z3 K; r4 Z% q
}% o. `6 l$ }0 `& Z6 ?# R! p
. h4 k0 S$ p4 \ // 将 arr[idx] 替换为 c3 h5 _- w& @$ f& i3 V3 }
// 维护 allIntervals 和 intervals
( n: x s. F4 ^ A' Y& C/ A' s // 返回单个字符的最长的子字符串长度
& d! m( a" a! r0 K( V1 A* n; C+ g private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {' L: e1 N( N! {( [
if (arr[idx] == c) {
9 u: a& m5 R' q' J return allIntervals.last().len;
& z& a8 o; D0 d }
5 }. a: s* M5 Y9 l8 D0 ~( y4 \9 h" x6 ~/ V
// 维护原字符 arr[idx] 的 interval( H: H* `% d5 Q; U5 s0 B
var treeSet = intervals.get(arr[idx]);
7 K( ?- n9 n# g Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可% L c9 j3 D3 |$ p. p
treeSet.remove(origin);. l/ C) B8 P4 y* _; `
allIntervals.remove(origin);* ~0 O# A$ q0 h* X9 d3 E
if (origin.start < idx) {
3 q( P1 Z {, T4 V4 z Y) j Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);& X7 M ~ f0 `2 k
treeSet.add(interval);( `: @/ c: A4 U1 o& g( B
allIntervals.add(interval);" j N3 b! `3 B7 W3 ?. t
}) ^( M6 H4 C% ~4 A
if (idx + 1 < origin.start + origin.len) {
2 j# ?, L- U: G) V" u6 o Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);8 ~* [ u; A( y, `1 u
treeSet.add(interval);% \6 V$ d Q- _: L3 i8 P6 V
allIntervals.add(interval);
9 \* E( d: Z9 u. K, U$ Z; u/ T# b }, w9 G. @1 Q9 L1 M; e
, u3 `9 c$ q+ Y // 维护新字符 c 的 interval
) T; d& y. t% e1 ^ treeSet = intervals.get(c);
( j0 P, |! z1 a2 S( }( X0 ]' F if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接* K* Y4 V! r0 c# F' v
Interval left = treeSet.floor(new Interval(idx - 1, 0, c));
! N! v$ C: n& T, a0 T. D Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));+ G% ?$ o( ]/ A3 J7 C& j# W
treeSet.remove(left);
/ L C8 M+ H* k7 d) n8 k" ~ treeSet.remove(right);3 n& k7 U/ R" S# E, ]! T+ d2 T% A
allIntervals.remove(left);
1 i8 L3 H P! r0 F% p allIntervals.remove(right);
4 y& d e1 O5 l, q- V6 h( \ Interval interval = new Interval(left.start, left.len + right.len + 1, c);
% Z! j" B% \ D. t treeSet.add(interval);8 R3 h+ C1 a- n- X! R8 c: h% H
allIntervals.add(interval);# [1 k2 |* J3 v$ x s
} else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接( G3 D" A e; ?; X+ {( ?2 |/ c
Interval left = treeSet.floor(new Interval(idx - 1, 0, c));
d8 {" i( U- M; o2 B treeSet.remove(left);" v( B; |' X" G0 h$ m" Y9 n1 h
allIntervals.remove(left);
: O! I# z# ^4 K( j# P7 H- N! _ Interval interval = new Interval(left.start, left.len + 1, c);
# G9 \! R' `( [9 D1 F! r0 ?" M, p treeSet.add(interval);
$ }7 S* _% Q4 I allIntervals.add(interval);9 o) B" F g# G( S% b
} else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接# ]7 n: p( }0 \
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));: L: s! k7 \, m r, s
treeSet.remove(right);
$ p0 I% c8 e7 e2 S& V allIntervals.remove(right);% N: f; k5 M, l: s4 Z
Interval interval = new Interval(idx, right.len + 1, c);8 |$ k& _( z* z: a, C
treeSet.add(interval);
$ T9 t6 G- K# O1 \" o8 U3 r# p5 v allIntervals.add(interval);3 f: T' y" x$ | c7 Q
} else { // 单独一个! Q+ ^4 c- E0 x2 Y5 ?7 c$ a# e
Interval interval = new Interval(idx, 1, c);
, u8 _/ V- v6 Q) \) T/ E treeSet.add(interval);
* G5 W8 O/ g5 z5 B$ W4 O8 ` allIntervals.add(interval);
! ?% z" d$ l, C }
6 m7 A6 J; }( k/ [2 }$ m, X/ g: E+ o3 _: q: k
arr[idx] = c;
( \5 b% ^7 \, D8 t: L) J0 l: ~ return allIntervals.last().len;
3 V: b9 o+ U0 L }
- ] ?" G! g5 _} |