登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 统计数组中峰和谷的数量】8 |9 c; w* f; K% v
5 W! x- {0 ~& ^" ~; s* u9 u/ X解题思路
6 U9 y, e* P+ B# n1 e先去重,再统计。
6 t: J, C" M& t
2 q$ n- n9 i8 ]' c# |代码展示5 x* |8 M2 V! c8 V
- ^: u$ p. J5 ]class Solution {
! k( |* C" {" | public int countHillValley(int[] nums) {7 B2 f% ^9 } m* ~1 f- b: Z
int len = 1;" O/ k/ ^7 U/ H* m- F& o
for (int i = 1; i < nums.length; i++) {
' t. u8 R7 T8 ]: L) {# |/ c0 n- Z if (nums[i] != nums[len - 1]) {0 f2 o$ f, r" H# r6 a% v$ j
nums[len] = nums[i]; d( T& l( ?) h) f6 E3 V$ w( x- f
len++;9 X! h5 g u' R/ j8 o h( N2 D
}
8 z1 L& ?" w' n! I v9 l }) G' j; ]* Q. @6 z% D$ `
int res = 0;
6 @1 i4 l; K1 }3 V# M r4 i$ L for (int i = 1; i < len - 1; i++) {1 T2 _9 f5 T0 M- N0 t, G
if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {
; V; ]% f8 a- r6 p! K% `6 h9 F res++;
. G. [7 f! W/ r. [ }
6 {& h6 m0 O; @3 H$ ] I* v }7 u8 C; F; E0 \. F9 y7 N
return res;- B7 d0 Q3 N! B
}
" i& N# c3 W+ H% i9 P' e, m4 ]}% f! ^! w# c( K( `
* _) S0 e2 i, _# @9 H' I9 R
( E- G9 v/ P; I n4 M# [【 NO.2 统计道路上的碰撞次数】8 f* e. [5 ]6 R' I# T- N1 |
" @& [* T. X, W# A" R2 _7 H解题思路
: {% S E" d! t从左到右遍历,维护左侧的车的状态,有两种:
" w2 n. _$ ?% u* h6 r4 W E
) q7 I2 ?$ w2 e k8 w9 f, P! h若干个向右行驶的
% q- M1 l* J/ d( S9 w. M' B: z/ p! I P' y! \6 p6 H8 E9 H
停止
5 M- ]+ N; i0 h% J: ^* j& f
4 x4 `2 d* H: |9 [; k% q' I3 U代码展示. ^7 m8 u7 Y2 {$ u
- b% C7 S" N; L9 K' p0 i9 z
class Solution {0 q! I$ _9 b# _2 d+ _
public int countCollisions(String directions) {3 n+ S2 n6 B2 g) y: s, O" T# V
int res = 0;. s! n0 C, p; N8 v8 u7 ~) T
int S = 0, R = 0;8 p+ p6 x8 J7 U3 F8 c3 T
for (char c : directions.toCharArray()) {: i" u$ r# t3 S2 p; R
if (c == 'L') {/ S: V2 \+ ?4 h; h% ?# r
if (S + R == 0) {
- K: M/ J5 ^0 l) X. Y% w continue;3 s! V0 S* p- ^
}
& z2 V" r9 l: h# b! L/ b; k if (R > 0) {
5 q, ^. w8 t5 `( T8 c res += R + 1;% n% p5 V' h3 x% b' V/ x g7 r
} else {) i7 W6 }, o. C$ V) h
res += S;4 F! D+ X6 J' Y
}
3 [- Y& j" Z. \( a. i9 E S = 1;
7 |# Q7 K* R! N3 v9 R! W: D R = 0;
6 ?1 q( B& U& w }
$ v0 r, @$ x9 u if (c == 'R') {$ _. ^. K' A4 p* F2 l$ C
S = 0;
/ Z$ D( b! Y. M6 L R++;/ ~! L3 l7 g8 P9 ` ~* [
}0 ^4 S( Y0 x$ Q
if (c == 'S') {
0 E( V$ ?2 P" U" i( G/ A; H res += R;
, X* {2 a4 n$ j0 r. `4 a S = 1;
4 o( @/ i4 F0 J R = 0;$ C0 y/ d8 K% L2 D% q, D
}$ E8 @6 _2 O% i Q
}) a8 A7 l6 u: g) C5 ], d- I4 l* T
return res;
, K5 O I: }( @ s5 ^ }
% X2 C0 b$ y& W( h+ `& F8 G1 V+ v}7 M, j* {7 M# `4 N
2 `* S# {: U0 Z, ^' z1 \
! G* [: P/ S5 z% }8 e+ k8 O6 h1 P4 g【 NO.3 射箭比赛中的最大得分】
2 c3 x/ `! P# Y9 T9 \: J0 G
& G4 }" d: e+ E* j# o4 C# C解题思路+ B% V) g( X) ]3 d3 ^
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
& K: S- G; I. b2 H. E; Q
8 o* U! E1 x: R# c贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
. N- a. C" r- [+ W5 I4 V- O& [. }9 s% r$ e! P: X' S9 d
最后多余的箭可以放到位置 0.; o3 g- y5 z3 x c9 x+ J
- |' s* K& J9 H, _; U ?
代码展示
3 K# J; o5 v( l2 c0 t: P
+ q$ f) P3 a/ ^/ w# C$ O% xclass Solution {
% \) Y4 K0 N$ j3 W- b8 l& K# u3 S public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {
7 A3 x" ~3 w& y int max = 0;8 Z, d! V3 Z& k) \7 c% `" e
int[] res = new int[12];, \7 l9 j. h% Q3 \: {# d- v. e% i
for (int i = 0; i < (1 << 11); i++) {
' X8 n, h5 E O/ Z+ r& M6 ^ int num = 0;
5 _/ D! Q( {% C1 @# o5 D, X int score = 0;
$ \9 B9 _8 O* u for (int j = 0; j < 11; j++) {
# g, _1 `7 x: u4 J: G7 A# i if ((i & (1 << j)) > 0) {: o: ]8 E( v& N5 z' U y# q
num += aliceArrows[j + 1] + 1;7 ]& n* ~4 J& H" I
score += j + 1;! H m; m' Z7 E! R% E) n6 T' U
}
- x1 h* N3 W; t! H; G' a }
* L: h/ b/ {" ?3 y7 v( ~' E if (num > numArrows) {: g1 |7 ~4 {. L$ M/ w3 e
continue;
/ Y' b8 c5 j! ] }7 [2 A0 f6 m) u) N
if (max < score) {3 G- g* H' \# R9 |1 Y
max = score;
" N0 I7 H1 j) z* x res[0] = numArrows - num; // 多余的箭: m5 `% J, f- [, U# R$ U0 O
for (int j = 0; j < 11; j++) {# D9 H7 H& u: r9 b" N5 u. d7 p: r
if ((i & (1 << j)) > 0) {( B; v9 |1 G( m* B: Z. E) F. y1 _
res[j + 1] = aliceArrows[j + 1] + 1;
# ~1 S5 F0 ]# ~* D ]: E' Q } else {
! K3 v$ [' O# d res[j + 1] = 0;
$ w/ q9 B- l2 {, O0 N' [ }
) C* A9 u0 d: g2 d4 ~4 e }& \7 W1 g$ Y' X2 E
}! \ v( j- `! {
}
( N( k* ?+ w- }: H5 ~# K return res;1 M( v1 f o8 D: a n
}$ R# H/ `$ ?, U$ G! l/ x/ F
}" g# V0 ?$ @+ D
; p! `; [& Y1 x0 V' L; F3 q) t
5 \# l" f! W7 o9 O) m' {( i# ?- s【 NO.4 由单个字符重复的最长子字符串】
& {9 d6 b2 b# @1 o
1 ^/ q( [, ~; o1 I7 @, m9 B0 _. b解题思路 W& t; @3 Q! m1 l j$ k+ y
灵活运用 TreeSet 即可,详见注释。
) W0 ^1 G/ w# h2 E+ M$ J
) x% j" e1 e, w. \代码展示2 [8 E, R4 {$ u0 h; M, }: ^% h4 U6 |
+ \2 t- Q# s' i0 t% K+ R
class Solution {9 p0 R x l; f' Q; u% W
% V$ K. D% d9 A& n/ u9 s. f
// 一个 Interval 表示一段连续的字符! g* p8 s1 c8 W' O m
static class Interval implements Comparable<Interval> {6 {1 b; c; ~+ R3 K* H
int start;
7 M" o& H1 l8 E$ i" s" R& l/ A int len;
3 D6 n( p/ o& I char c;
$ ?4 P A/ g" Z1 k1 W/ V7 G7 [6 ^) j- L
public Interval(int start, int len, char c) {
+ k! ?( l6 F1 ]! X1 s this.start = start;
- n7 U R: J( c9 D. B0 O this.len = len;
6 {' |4 T- v8 C& `" e: g u this.c = c;
S% B0 W4 l, V }, q( g- R8 W4 |/ _7 Q( E
. b, X$ ?# L& c3 }. a9 o( S9 L
@Override0 {0 e$ T" y3 J) g
public int compareTo(Interval o) {
6 M. K: e* R7 {+ n* I# ?" f! T if (len != o.len) {2 K+ S9 {: V- ?7 O" B
return len - o.len;, }. o% V- _: ^# W
}) {$ T1 Z" ~: |8 n/ U
if (start != o.start) {3 _( O' z, u. w) o' y1 }- f- J
return start - o.start;4 P- h! B# _0 i; u- q; r8 Y
}
1 C# I" X; z+ X return c - o.c;4 Q; s5 Z5 z. F: r4 m
}
9 s" \( D4 W; {1 e2 x }: ?. |+ v, j6 j" o& q/ O
+ N' G, H; o" \% u7 }/ C8 i! y public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
1 o# W: s X6 G6 c3 W4 m // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理9 o5 @1 w2 a% e5 }
s = "_" + s + "_";9 C3 F2 u3 R$ m4 R% K
// allIntervals 按照 len 排序全部的区间
$ _2 x6 p7 T" }+ D TreeSet<Interval> allIntervals = new TreeSet<>();
1 x8 u, X# ~7 J. e6 A. r // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序
1 N. t& s3 b' d- n; S Map<Character, TreeSet<Interval>> intervals = new HashMap<>();' H$ g9 u& n c4 o6 w
for (char c = 'a'; c <= 'z'; c++) {
& N/ W. E& Q% E8 c) ]" |( l( p intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));7 e" l v7 e! m
}
8 ~3 n4 W* h3 d8 }4 m5 ?1 w intervals.put('_', new TreeSet<>());
# A7 F- i- B' ?2 B$ j# I& h) K: T
, j* j7 ]8 Z) M$ _) |$ L // 遍历 s 维护 intervals 和 allIntervals0 Y3 g8 B' l9 E: u t9 c. {
int last = 0;1 t$ a% r0 s1 b: v' W* g
for (int i = 1; i < s.length(); i++) { o, N7 Z, o' ]7 F" a4 d {. q
if (s.charAt(i) == s.charAt(last)) {
: b1 }9 F+ f9 E& x continue;& S/ G1 M. f4 t3 \( H9 o- S
}( c! B7 L- a' J2 d7 U
Interval interval = new Interval(last, i - last, s.charAt(last));
+ Z& t3 Q( C$ {% L allIntervals.add(interval);, t( V% G9 v- J9 ^; ~
intervals.get(s.charAt(last)).add(interval);5 ~9 H2 B' H2 @8 G q6 d$ L9 W5 A
last = i;
4 W4 N# h$ |, _8 w5 I: O }0 K4 @; s% A3 b2 o
Interval interval = new Interval(last, s.length() - last, s.charAt(last));
: ~( A% U" F7 i/ ~3 w allIntervals.add(interval);
4 h8 K* E( [6 R' B% ` intervals.get(s.charAt(last)).add(interval);
" X. r0 Y( l- {. Z% z4 l3 H7 _- c4 g$ l, d0 P0 t- V H, @
// 每次 query 调用 maintain 维护 intervals 和 allIntervals4 G6 o3 ~" F E+ L! Q% v( ~
int[] res = new int[queryIndices.length];1 ~4 g& G6 I \% ^7 J( {
char[] arr = s.toCharArray();: \# q' _( u- w9 w/ p9 N2 T5 w; n
for (int i = 0; i < queryIndices.length; i++) {6 T% @6 F* j* `
res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));
! _3 {3 |1 J3 K! K9 D7 }1 b }9 Z% b8 \2 r7 b) F
return res;
2 M% {" f' W& k( c5 X" O }% w: h, u* T4 w. Y; T
! V }3 a5 k8 D7 ]/ u ?, i" |! C8 [
// 将 arr[idx] 替换为 c( s. d9 S4 X; Y! T- `. q2 c
// 维护 allIntervals 和 intervals: U( m7 a6 S8 @' ^0 b# O: ~( ~9 B% a9 e
// 返回单个字符的最长的子字符串长度
* P- Y6 u& ~9 c( o private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {' ?! A2 F! `* U- a
if (arr[idx] == c) {. A1 _9 n: ~; D6 r8 [: h+ Z6 s& p$ c1 |
return allIntervals.last().len;# l9 Z5 @" @4 v e) p
}
. P* v' [, Q! x2 b
0 q' l/ P0 }. n" s2 s // 维护原字符 arr[idx] 的 interval' A( T5 Z9 @8 I# g/ B4 }0 C
var treeSet = intervals.get(arr[idx]);
5 Y& y: U3 G6 H" w Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可
; z; J6 P5 K1 C. a: w! J/ H treeSet.remove(origin);" S9 q2 a' C* ?; K& \- X
allIntervals.remove(origin);
1 |5 G. _% g7 ?; E) w if (origin.start < idx) {
+ x: `" E2 a/ K; k) Z Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);1 y" B# \3 T1 `- d, w
treeSet.add(interval);
. f% Q! {3 z% z3 M9 p/ ?* m allIntervals.add(interval);
; V' b8 P7 Q5 T v$ A }
) {& j% n2 i) c8 K, e if (idx + 1 < origin.start + origin.len) {
/ O/ E7 }! Q! T6 C4 e" X# a9 q! S Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);6 f9 W0 j$ L4 A! r5 r
treeSet.add(interval);" u9 d: J8 G6 d# s
allIntervals.add(interval);% K8 W3 j, f, D9 H @" ]
}
6 ]% y# ^( L1 \+ N2 E o# }- j( j
; G4 D3 {5 h* k. a6 k // 维护新字符 c 的 interval
! N$ S/ M( h* L' F2 ~ treeSet = intervals.get(c);
4 B) x- Q" J D& T1 B; k) q6 b7 c if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接
; |- Z b A2 q7 s n Interval left = treeSet.floor(new Interval(idx - 1, 0, c));
2 A/ I# O7 V# y Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
- ^" ?3 G7 A7 t4 P" b3 r treeSet.remove(left);2 E$ O- n; T( V2 ]5 g0 ?! V3 i' q% W* ^
treeSet.remove(right);
% v5 |5 T x7 e3 G$ U5 J a1 n! d9 B, x allIntervals.remove(left);5 p% V0 c: J6 i9 o0 Z5 O) E
allIntervals.remove(right);
v1 ?$ t9 j& B" D3 e# p Interval interval = new Interval(left.start, left.len + right.len + 1, c);
- e- f1 M5 m/ f; @ Y6 D treeSet.add(interval);
9 i0 c* x( }" M1 ^: y$ ~ allIntervals.add(interval);6 o1 y% U* f( u: K- }
} else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接
, ^/ b Y. U% ^' z$ a* \% s4 l Interval left = treeSet.floor(new Interval(idx - 1, 0, c));7 F: C ?9 Y1 V4 U' w+ h
treeSet.remove(left);
; f8 v: H, U! K allIntervals.remove(left);
- k. h3 m, X5 }$ Z. G Interval interval = new Interval(left.start, left.len + 1, c);
) h! ^- R& M% l) g treeSet.add(interval);
( C, r9 M* V! Z; n7 f/ v2 U0 g% d- [ allIntervals.add(interval);
; g7 t X* t/ V) j* P; E9 S+ m3 K } else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接
9 e/ T) R. I5 A) _' L% c+ Y Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
( f3 ]" j( B7 U8 f8 t2 ~% m treeSet.remove(right);
* x- b9 r6 Y+ H( K allIntervals.remove(right);
3 l% v+ W P- @6 p6 k- w Interval interval = new Interval(idx, right.len + 1, c);
/ g5 C4 Q1 D( V) f! D( I treeSet.add(interval);
6 u0 Q6 s' k3 I" }" v6 w allIntervals.add(interval);0 W0 Z" m' }( l" A" P
} else { // 单独一个
! |+ w G* p I4 M. m1 ~1 @9 I Interval interval = new Interval(idx, 1, c);
6 z6 z& n5 f" x: N% q* z% ]: Q* Q- l treeSet.add(interval);- H* b1 O7 Y) p5 J
allIntervals.add(interval);6 f. e# Z) }) o* P9 @- m
}; l3 D1 S7 r" D; _
* t/ G2 H& A' @8 ]: e
arr[idx] = c;
i( @5 s3 z4 y: I7 y: b return allIntervals.last().len;! T S( I( y- _& H7 \
}
; ~7 G% V& f" b} |