登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 统计数组中峰和谷的数量】
- w, ~# j$ V! x) C; i# h3 M' T+ A- ^# D- D3 I
解题思路
) v2 G5 ]* E9 M5 @9 O: O先去重,再统计。
, G1 x, s9 P; _) D
7 v9 E! K2 h- r. {- n代码展示
- E$ j4 h9 s; G# \* b5 e# f, e) a( `0 A5 V8 K1 {' S a6 e
class Solution {
9 Y. r5 m3 P1 P% o5 u public int countHillValley(int[] nums) {6 M* i- C5 w; M: |
int len = 1;
. X$ v& T5 e) ~: \5 R( ^ for (int i = 1; i < nums.length; i++) {& G4 a3 a2 w* p/ Z" S' C+ P+ ^
if (nums[i] != nums[len - 1]) {0 k+ e% \) x/ z
nums[len] = nums[i];
) C- L1 @2 M1 c4 ]1 m. Z7 N7 R; O& m len++; H" H1 C" h2 u0 K9 m5 i' `5 ^
}" |; i% z: D6 L$ t/ _4 f @9 c
}' L1 F- S4 U `
int res = 0;
, E. P5 { {! [) W! T for (int i = 1; i < len - 1; i++) {* f( o& T9 }9 e% u9 G/ y" \
if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {4 H' M/ i) s" E+ n+ ?- K" h
res++;# i9 q# j. Q" I, Q& u
}7 ~, Z1 l4 i& }" T: |7 j; f' Z+ F* b
}$ Q: I. _6 z% \( [' B
return res;
7 w' E1 j0 B+ e8 n: G( x }
1 ]/ o2 q5 \$ ? i}8 m) A; {: I' A: U3 m. H$ }
1 i8 t, T1 M* O+ F4 c
( y/ l- u% {" m, U2 P/ Z
【 NO.2 统计道路上的碰撞次数】1 p8 `/ f9 ~' P2 I& H3 K3 _/ P: d
& `7 M: y5 C% z, g/ P+ A# k解题思路6 L8 _/ H: J. W- H) L, {
从左到右遍历,维护左侧的车的状态,有两种:2 \) D' s( V8 I% d, Y$ {8 j
3 _4 j x! z7 q: d
若干个向右行驶的5 Y$ Y* `6 r+ q: t+ Q5 N. M5 N& Z
1 D! v; L# r& t5 U" i9 Y
停止
/ A* f* ?1 Y9 o
# Y" }& }1 L) r代码展示
, o2 p5 S+ {3 ?# c3 n5 l/ ?8 a; a6 J- _ b7 h: Q
class Solution {
8 Y! `# R. f6 @& C) z public int countCollisions(String directions) {
. X: w+ ?: z7 T2 }7 ?' f int res = 0;3 i# v& } W' q8 }
int S = 0, R = 0;
+ J: d- G2 Y4 P) R7 F: E% \/ h for (char c : directions.toCharArray()) {- _; ^- z+ p( N; ]9 K
if (c == 'L') {: C1 |4 F( A: q5 _$ N+ ]1 m
if (S + R == 0) {* K) E+ @% ^! `3 a0 A
continue;
* Y. Y5 E( A) [+ t( W }
& R" m% [, |' z- o) Q if (R > 0) {
' t0 _9 i/ I& @0 A res += R + 1;
2 j7 G9 l4 P' y% d- A+ t, X0 k } else {
5 u5 L- m+ Z# K3 B+ C5 W. n res += S;: X4 w+ S7 ] t
}, f9 Q2 m5 S z& ^
S = 1;7 C6 K8 |; u! T8 l
R = 0;
! C/ u! S; }7 f. s8 j }
0 j: Q G# N+ `5 h5 B if (c == 'R') {/ f1 ~4 ^1 ?: ] L! A. o" D+ s
S = 0;
: w$ A9 |3 v4 V! g R++;
# v% a" f4 s4 {4 e8 `# u% P }" i* Z) k! B% r% _: Z- ^
if (c == 'S') {. E2 {. r& x' o3 u) N0 D. x7 Y8 b
res += R;- ~9 U+ K, A6 U- c
S = 1;
( D# g& q. i. S/ X7 K3 Y* L R = 0;1 P$ M. Z7 S3 A1 {/ m2 v$ h& U# _. G
}
3 \5 V( o+ v" u8 f: ]" u }
( [8 @: L* n# _: R return res;0 ^" L6 ^0 @% y# [* e h8 C
}" L4 p- c v# x& ~4 ^
}- x+ @8 T) }% }, m+ T* @5 ^2 V; O
n' C" L& Y; F
" y( u- H- \. F$ M8 {+ w3 X【 NO.3 射箭比赛中的最大得分】5 u8 i1 g0 i3 ^1 h
' B1 c' x! a& Z0 b7 \! f" ~
解题思路( i2 P- k: ?6 c3 h- v" p7 y U
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
$ s% e$ F" r. d, O1 B! S. r/ J" n. c4 r: [* ?1 _% w
贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
5 `- [& y, l' N. N' ~. [
# Q9 W! b% l* v$ v最后多余的箭可以放到位置 0.
. p( s9 C* H8 p6 w( h3 Q4 W# ^/ v
代码展示- ^) k0 r) w0 m4 M d( ~7 Q5 S
; h' H- L( p1 \9 iclass Solution {
- d+ _! u& V! c8 Z8 X$ Y public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {6 a6 t. o- H: k6 i. g
int max = 0;4 O6 U5 L: Z5 b0 s$ p# r: x5 D
int[] res = new int[12];
9 l4 y2 \2 q5 l4 o for (int i = 0; i < (1 << 11); i++) {
8 R# C" A2 @ p( b3 [ int num = 0;0 l. P+ _, ^- t4 }* [
int score = 0;) ^) H( T- z, g( g) V
for (int j = 0; j < 11; j++) {( E% K4 m3 {( h2 |4 }
if ((i & (1 << j)) > 0) {
- R; }* o; S# c Y" x num += aliceArrows[j + 1] + 1;" e* z1 ^/ H9 e- J7 Q3 m [
score += j + 1;
% E' z# L( z. ~; }( M& a u [* j }$ d6 ?0 E4 F) J1 E- l
}
! K- x# M, x$ u% s( c2 G if (num > numArrows) {9 p" J' w. [6 \$ @
continue;4 N* V/ r- Z0 H0 Z/ ~! D( b4 y1 ]% n% e
}
6 T! H6 @4 ^- `: ~2 _ if (max < score) {0 O8 ^' }' E# R7 }; k7 v
max = score;
4 e$ s% U2 K& c7 e& T res[0] = numArrows - num; // 多余的箭3 [% T7 V1 o5 X
for (int j = 0; j < 11; j++) {. P% w$ J4 T, i6 q- \. y9 G
if ((i & (1 << j)) > 0) {. N; E2 i& b7 {+ ]0 g
res[j + 1] = aliceArrows[j + 1] + 1;
- n% X3 c1 w; }4 g4 f, S+ l W5 ? } else {
8 X6 N: s0 x _ res[j + 1] = 0;: h9 n2 E" G# @% `$ [
}
3 d5 J9 b( D; X, q6 S7 n0 ~( @4 u }
, I, N5 S9 n6 ?5 ?* N+ @# v }
- T, r+ ^: {) J, G* }- i# m }# Y9 U! V% p! U- g- q4 L1 n
return res;
$ A' g% ~ `) A& [6 k7 H, F }
: H8 K- W( k9 ]. `}
& f0 F' Y, ^- x4 `# G9 C$ I C5 k; Z0 q: s5 t/ Q# K
9 g5 q- K0 J: {1 H T
【 NO.4 由单个字符重复的最长子字符串】$ V4 g0 z; {, P
$ W$ r7 I3 h0 f- k解题思路* u7 C; g" O) O' s2 U* J
灵活运用 TreeSet 即可,详见注释。8 p- H$ u5 |1 h3 A; x" J
- `* J6 R" X/ g& _& J- H0 u代码展示% s+ g' s" f+ c ]) N5 p. Z5 v1 h J
6 i& B% W! D0 J u3 z! d5 oclass Solution {8 n. y2 M- q) u- p3 @5 @
7 d1 C* o) C- @ // 一个 Interval 表示一段连续的字符
3 E7 E/ ^( k. _) i" l static class Interval implements Comparable<Interval> {3 y% h- ]8 y C5 c0 d7 ^
int start;
9 L, ^: U0 l7 q3 F int len;5 n+ z# u2 P2 X. M$ h h
char c;" ~# H6 W/ F& T' b6 S
# B6 |, ?0 @2 ~ public Interval(int start, int len, char c) {1 s% D4 |& x' V E8 S4 O0 _) T4 r2 c
this.start = start;
6 A0 z" B5 c! ]. d this.len = len;
7 n8 P# Y3 b5 d" d k& R. e% p this.c = c;& S6 W' @/ k( K( q6 A$ H5 Q' A. q
}
5 j+ U# p/ A) c* P$ O
% q, @1 i: ^$ y' v( B. H% s9 Y @Override+ d P- }- u! L! f3 G
public int compareTo(Interval o) {. i9 ^- @& |' U" a, p' W5 z
if (len != o.len) {
: E# D8 _ Z! O( U return len - o.len;
3 ]: P6 C4 { `) @ }& P" f: y- j0 L5 ?5 \
if (start != o.start) {
$ i+ e; `0 v0 j" H7 p ^& t' w return start - o.start;) E0 G4 d0 h+ }
}
3 Z! L+ ^$ O" S v- U/ w \& w return c - o.c;
' V- N, I0 J$ I5 ? }$ q5 |; x7 H) {! Y
}
4 L6 F0 \& k. V- e, C- y1 @* s6 d" r4 g
public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
+ ~! \ ]8 ]5 ?3 y$ u // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理' f4 e- l' u' S' S1 |+ X- F3 t
s = "_" + s + "_";% A( ^' E* h, p1 k/ Y
// allIntervals 按照 len 排序全部的区间# I3 O& _$ [) _7 O: r W; P
TreeSet<Interval> allIntervals = new TreeSet<>();7 i" c- {2 T0 j. m# n! `) B
// intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序$ n# Q9 Y. s/ X. s4 `5 |
Map<Character, TreeSet<Interval>> intervals = new HashMap<>();* A. _" E2 o: V' s3 u/ m) w
for (char c = 'a'; c <= 'z'; c++) {
; ]/ ? E$ e$ o8 { B/ P7 R3 x intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));0 g' q- \( I. _7 }
}1 W8 d' Z5 W: M
intervals.put('_', new TreeSet<>());
4 M6 V8 U. T9 F0 L7 \; H- n! ~4 Y/ m& T1 C/ U
// 遍历 s 维护 intervals 和 allIntervals. L) g& N, h s& E" f1 b J
int last = 0;
. d1 _% _, s# c+ ]2 f for (int i = 1; i < s.length(); i++) {
4 a1 Y4 B _( |7 T0 I" P$ @ if (s.charAt(i) == s.charAt(last)) {. F. D5 {8 Z; }. v: T
continue;
% Y) \- b& J& P }( p8 ?& G% x8 X( t% O
Interval interval = new Interval(last, i - last, s.charAt(last));, A' _' x0 L. w- y
allIntervals.add(interval);: M6 ]; n, }9 O4 h; A9 m4 o/ e# X
intervals.get(s.charAt(last)).add(interval);
( \% W, u- a& ], t# b m last = i;
7 [/ ~6 s4 S8 R }
! {1 V' P/ B$ S" L Interval interval = new Interval(last, s.length() - last, s.charAt(last));
2 f% D, |1 x( H/ W# q3 N allIntervals.add(interval);
/ C4 {6 x! U; t* ^1 m6 [2 f5 j intervals.get(s.charAt(last)).add(interval);% o4 P% ]- t/ s" p
* m8 f* {$ D. I; H
// 每次 query 调用 maintain 维护 intervals 和 allIntervals
4 @. E) w, k' g1 W* l int[] res = new int[queryIndices.length];
: \" g# K6 \4 {1 ]) I4 w: ?* | char[] arr = s.toCharArray();; w7 B% k9 d" n/ w; W5 R
for (int i = 0; i < queryIndices.length; i++) {- p1 P& P. c: ^; c
res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));6 v s7 s4 v( n# x$ o. C. N' O
}
( y) a8 L# L; W" s return res;5 e* a6 E# d% I; V: s0 o) x) o
}
4 k6 W) n! J4 h( M0 I
w# L3 i6 I1 h! W // 将 arr[idx] 替换为 c
2 t, S. ~5 p2 q/ {' q // 维护 allIntervals 和 intervals
2 _% W0 H4 D+ S5 k1 a! D# ?+ A // 返回单个字符的最长的子字符串长度
( u6 f" }2 X% [3 r2 ? private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {- P$ l5 o' b. j Q: ~+ t* \2 b
if (arr[idx] == c) {; D. D: z2 H# i8 G- S" @+ i1 v
return allIntervals.last().len;. P' O& {6 s! Q- x8 ~2 R; Z+ d
}& b& ~& @0 B* B. K4 N
( E+ C$ F: ^1 x6 O( a" W# _$ `) J4 R
// 维护原字符 arr[idx] 的 interval; Z& F4 I1 q9 }$ H4 x! l
var treeSet = intervals.get(arr[idx]);- h& X ^% v, ?: q5 j) F: v
Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可) S2 G/ L, a+ ]* V3 L* a2 \
treeSet.remove(origin);
; J, y9 n p$ F' W allIntervals.remove(origin);
& H% m+ T2 U' N if (origin.start < idx) {
& @) ?% O/ C* ?" x# g Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
8 ~7 j6 m0 S$ D; g$ ^; o; c treeSet.add(interval);" c+ @! J4 x$ _) H/ `) w* [4 @$ ^) s
allIntervals.add(interval);
8 |3 C. H0 ?" ~9 L }
/ D" S" {* C2 t: Y4 _2 `& | if (idx + 1 < origin.start + origin.len) {$ C# \: P3 Z; ~8 g" @2 V
Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);
8 T' n7 a# |4 a treeSet.add(interval);
. Y* m K# _, {! B% R allIntervals.add(interval);! W/ `9 B8 c+ r/ ~. M0 H- E5 d3 ^
}
" ~# H2 V" u% ]3 ~- F/ R) ~! c
! B% A* V8 }* s5 e: B, u$ | // 维护新字符 c 的 interval6 O1 [: g" Q' ~' x, S8 e4 b
treeSet = intervals.get(c);
. c3 ~0 f( G' M% I# b% [ if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接
o a; l0 _4 }. p3 u( B0 _ G Interval left = treeSet.floor(new Interval(idx - 1, 0, c));( D% u. b m! [/ e" h6 l
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));/ O0 [* U$ b% |- b! o& y5 B1 g: N
treeSet.remove(left);4 N$ F5 ]4 ~4 O2 t$ @
treeSet.remove(right);
/ ?$ K5 g+ ?$ F" w3 Z, _ allIntervals.remove(left);- `8 h0 S3 x" O& o
allIntervals.remove(right);+ V% p# F0 A4 `5 s1 O+ o5 n' H
Interval interval = new Interval(left.start, left.len + right.len + 1, c);4 f; |% j7 L8 M: p2 L( k
treeSet.add(interval);: \$ }1 e, d- T, A% n% r2 k; W
allIntervals.add(interval);
+ ]& |( m" w; q* o) l" J: E } else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接
1 b: o" B, u3 H Interval left = treeSet.floor(new Interval(idx - 1, 0, c));. w v3 P+ `1 g5 Y
treeSet.remove(left);
9 ?) {6 y9 c+ M allIntervals.remove(left);" w* G9 M$ w3 W6 B' ~
Interval interval = new Interval(left.start, left.len + 1, c);6 F7 V* d ~. _
treeSet.add(interval);, I w! Z, }; m* K; E7 j7 v
allIntervals.add(interval);
- y- ^$ y) M* S9 g } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接: S( _5 b8 S! H/ [8 L3 C5 B
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));' I$ Y% X" T/ ^: `& e/ P5 B, S
treeSet.remove(right);
! f/ Q3 o& i( O: W; j( a allIntervals.remove(right);" q* E- j! B: k8 ]
Interval interval = new Interval(idx, right.len + 1, c);
- u! w8 u3 E/ w9 \( b, ]0 D treeSet.add(interval);
$ [, b6 Z% o" {6 A4 a+ V allIntervals.add(interval);
8 u2 }) W v' k' b } else { // 单独一个
) t; [* Z0 L8 e" r2 S' r5 a Interval interval = new Interval(idx, 1, c);
4 D' F- V. N) U4 x treeSet.add(interval);
9 j. w+ A* K- P; }6 j) v allIntervals.add(interval);
2 S: }1 W: p8 T1 D }
9 i6 W6 B' f" M+ s. i) s9 v: R
$ {7 \ r6 H% ^5 i) p# ? arr[idx] = c;
8 `8 `/ `# i% r7 \9 T' e: e3 A return allIntervals.last().len;' K" R, |! c! C. a- t) C4 @: |
}
2 q% J5 Z0 I5 Q0 X# i8 i4 U- w} |