登录后可回复主题
您需要 登录 才可以下载或查看,没有帐号?注册账号
x
【 NO.1 统计数组中峰和谷的数量】 Y1 c+ g0 @' C7 c& X& G
' T3 K+ `7 [4 V* H- g解题思路1 o( M9 j6 N- I I) y5 b1 l8 W
先去重,再统计。
- p" c# l. \5 F" I/ n
k0 P+ h2 }% Q6 \$ v- }# d代码展示1 V9 a. q- B8 w6 C
* X5 c' h# c& _0 m7 `$ w6 T- |
class Solution {
! V1 M* p% \6 I( E) d+ M3 Z public int countHillValley(int[] nums) {
2 q$ E6 B3 g5 F- d! ? int len = 1;
2 e) Y% k3 p5 } for (int i = 1; i < nums.length; i++) {6 r U+ S4 _0 L& @& ?7 r& s* E
if (nums[i] != nums[len - 1]) {6 i" {$ K0 ?: h* T5 ~# k( s
nums[len] = nums[i];
- L! | e8 O/ U6 B; y len++;$ P9 A2 U) A* t' Z0 Z; w
}
# Y9 O( O' Q" L }
! d* k9 C; P# e1 V: V* o3 u int res = 0;) c! A4 l5 x5 c, m
for (int i = 1; i < len - 1; i++) {
3 n$ c3 a! B" r& F! ^- F, ] if (nums[i - 1] < nums[i] == nums[i + 1] < nums[i]) {- j$ S5 i2 \; @9 w0 O6 Z
res++;" A, B6 h; s8 @$ \ H3 }7 v
}9 K2 g4 N6 W7 o! R4 a$ o
}
2 B; v1 g: J+ U8 Y return res;0 n5 c ]1 X2 E4 ^! ?7 n
}
# e+ X% l& Q' l/ }* A( P3 k* U}! n. {7 W3 w/ v
1 y9 d& s3 V* a
0 j; {4 R' w6 }( _" t【 NO.2 统计道路上的碰撞次数】
. L1 f" Q, h! i7 I3 d4 d
( c1 P4 F4 |2 o, m- q! ~+ T解题思路
1 A; k( @7 g$ l% ~& |. d% b6 s从左到右遍历,维护左侧的车的状态,有两种:
7 D V! I) a$ X6 z# T, M- O
; k p2 C4 J/ s若干个向右行驶的7 \1 ?, t, P; g4 v0 L
- O) N$ k& [& W停止9 D" I" ]2 O" V& u, Y5 @7 d7 Y
1 @5 T; C- k5 Z j _( M
代码展示
' e. j5 z5 n$ o6 z/ c/ j T- T1 K: j; \) s B- |
class Solution {
+ _, a6 H, \( y' X" ? public int countCollisions(String directions) {
% I5 _/ I/ [3 c% p int res = 0;
$ ^& @2 |/ V/ \6 D, y int S = 0, R = 0;: ~5 a; R" L) p# p0 E5 i8 e' R
for (char c : directions.toCharArray()) {5 |8 W' `/ b* q5 W% L) V6 N. ^3 Y
if (c == 'L') {
4 Y2 @5 m: H! `6 |- B( K if (S + R == 0) {9 w& M) B; m! ]* Y4 M
continue;
+ O$ W; m3 `8 I }
X& }1 v C' S! C if (R > 0) {0 J: X6 m7 O+ a! q5 l
res += R + 1;
" U: e8 Z' k, s p( ~ } else {6 v, @: W3 {5 Q; W" H# [
res += S;
( m8 u$ }: x3 i }
) B3 W2 Y8 g$ L/ g- | S = 1;
, e9 c4 T5 f% u! [" |/ Z6 y; v R = 0;
# ~* Z6 }9 z; m2 N; K: G) W }
K7 w* |; S% U0 N if (c == 'R') {
* w, K6 ^; s* H6 C. V+ h6 P x S = 0;
( ]+ P. U" n1 B$ E2 j/ G' _+ B R++;4 ~" L7 t+ L: v/ q. A
}
; e I! L7 I6 T/ ~- v$ Y if (c == 'S') {3 Q9 S) ~ j+ k8 `' }
res += R;' x8 [3 I3 |% |
S = 1;1 a& Y0 v3 G3 b- Y" i* g
R = 0;
: K$ T, X x7 b4 `, R- s/ T; F }& L6 a/ c5 X0 R
}8 |, ]1 {# m# \1 d0 U
return res;% I, \6 ?# B. f: Y( t
}
9 f( a0 U& b) R# }* f3 c} u- e5 R# n7 a, F$ m
9 M9 q/ v9 Z' j1 e+ z; w+ W
8 T2 I2 q! c" w* @2 R5 r5 }) q【 NO.3 射箭比赛中的最大得分】
( u9 @. ^0 P# J8 j7 l' ?2 \& a+ ]1 @$ d2 _; {
解题思路2 a- u/ l3 i) f" E, ^
枚举所有的情况即可,实际一共有 11 个得分位置,枚举 Bob 要在哪些位置得分。
/ t; ]) [# `4 S( }2 L- D; m
. o3 @1 y. t9 {贪心地,当 Bob 要在位置 i 得分时,只需要花费 aliceArrows[i] + 1 支箭。
v2 q8 Y+ N9 q9 Q2 e- Q3 ^* E' t4 ?" \/ H. b
最后多余的箭可以放到位置 0.; @# r3 z& V5 K, b1 d
! b/ r$ k2 I3 ?1 w* X0 y
代码展示
1 Z4 o; M' B. @4 w5 _; b/ B5 I: v' d& v7 q8 i
class Solution {
& i% {2 M0 ~5 R public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {
3 D* D3 E' [8 B int max = 0;
/ ]6 |7 W5 e) @. h1 v; o# {$ u int[] res = new int[12];
7 s) F# Y9 ^+ ?5 q5 R e for (int i = 0; i < (1 << 11); i++) {
" A- O8 C0 N4 K1 y, p6 U int num = 0;* n* ?) B& O2 G5 T1 T3 X
int score = 0;
4 K$ v2 o- R) K8 S* R7 o for (int j = 0; j < 11; j++) {
1 w' T9 `4 c0 U/ Y if ((i & (1 << j)) > 0) {
# b- f% Y4 g7 @ num += aliceArrows[j + 1] + 1;. N) S8 L5 |: c, x) i1 j0 ^( {) \
score += j + 1;' Y9 y. B4 [) N/ W- }5 N
}
8 b4 Z5 v6 d. f) J }
; E$ q+ q9 I* Q: U u5 v8 r if (num > numArrows) {
7 b+ d. i5 [8 E1 D- y continue;
6 F j X* B i }
/ B, B7 K% Z" J" R; q if (max < score) {
* b/ A; o. o9 z3 j. L% ? max = score;
& Z7 A1 q. |& U# h res[0] = numArrows - num; // 多余的箭8 N8 N" M8 N9 t! a9 {
for (int j = 0; j < 11; j++) {
5 d0 v; r7 t) ~) }9 n0 f9 u1 b* M if ((i & (1 << j)) > 0) {: e% A( U$ Z% _; L ~) ~
res[j + 1] = aliceArrows[j + 1] + 1;6 A6 D$ y. I( }' z' Z
} else {) `! p* B) l0 V3 w) i1 {; e
res[j + 1] = 0;
0 ?7 e5 R# B' @2 g. F- Y, u7 G, K }9 N$ p- `% j) j; K
}. \% w% D+ W. I* v C- x
}
6 N7 i( S4 I8 V" N }) f8 l3 w* N1 b/ {" P- U
return res;
) c/ s+ C5 w5 y }
. d3 r. ~. F! R9 I2 f& ~}
4 D3 A$ @/ N1 j2 g$ g0 A0 ?" X! E$ t- {' M
. Z5 l. T. s' I【 NO.4 由单个字符重复的最长子字符串】
+ R# [: o: w4 _# k
$ x! ]1 n, ~) m# K) A解题思路' Z. g# J% i. z- `* o5 Q" B
灵活运用 TreeSet 即可,详见注释。
$ p* c* \2 j( M8 v1 K: y/ m# n- ]+ t6 ~: s3 W" \( R
代码展示
& q0 W% o% z& }. S8 u1 r$ z Y
( m5 G G$ `5 Mclass Solution {, }; \5 j( ~ J2 M
+ n# X( Q! `2 _" n" I
// 一个 Interval 表示一段连续的字符
. T% H0 n" X2 s# [1 f7 Q. s. g4 l static class Interval implements Comparable<Interval> {
# x J( t# y5 \9 ^0 _+ j* i int start;
# V9 p7 G" _2 y6 F& M% B int len;, [1 S4 a8 ^: i5 S) c( U
char c;
Q) u# a9 S: U, q; u' m* d; V% c; q! S; z/ |0 B2 s
public Interval(int start, int len, char c) {
4 ^* y- U8 o: a- G this.start = start;( W! {& y9 S' y1 W9 O4 c q
this.len = len;
0 }1 h6 i' F' c+ W& `3 Y this.c = c;* \+ D; R4 v. i- b. I
}2 [$ I5 _# H% g% [2 A C
; |; q' `1 C& J! e N; y5 \ @Override
$ h( V, v q$ s/ k% H public int compareTo(Interval o) {- ^( I' N4 p* G" y/ R1 T5 ^/ f
if (len != o.len) {- u* w4 n! W& w' F% Z
return len - o.len;1 V0 x0 C0 U: c' ^1 S8 l* u
}' e9 o6 r. l9 M
if (start != o.start) {5 \- U' ?! Z3 I- U1 J
return start - o.start;9 m( w# I% h) N$ `3 g! r1 M, m
}
, ?* V& R* \) b* s0 G return c - o.c;5 r4 M; o6 n" b* A: Z" O+ N
}2 {1 L! m9 q8 M8 _! A5 f, A
}
5 N" b( M& Q7 K2 d" E! V& g- s7 G$ C9 R. v! K! i# ~1 r
public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
[0 E2 f8 K- b6 [ // 首尾新增两个其他字符,这样相当于 queryIndices 不会修改字符串首尾,便于后续的处理: V8 c& L; |+ V( k, A" p& A
s = "_" + s + "_";
- Q1 B8 \2 q9 M, q# _ // allIntervals 按照 len 排序全部的区间
" _8 q; u' l) _/ V5 u6 z; } TreeSet<Interval> allIntervals = new TreeSet<>();
! E2 A3 ~3 P) `8 z( o6 J7 L // intervals 按照字符聚合区间,即 intervals.get('a') 表示字符 a 的全部区间,并且按照起始位置排序
. \, M- T. y6 g3 ~! \6 V- g Map<Character, TreeSet<Interval>> intervals = new HashMap<>(); x) [, G$ h, w) v. F3 }9 e
for (char c = 'a'; c <= 'z'; c++) {
& d% q# i5 e& h* P5 N intervals.put(c, new TreeSet<>(Comparator.comparingInt(o -> o.start)));( Q/ I7 t6 G3 y( t% T
}
$ z- q7 W( n) C6 q! y8 k intervals.put('_', new TreeSet<>());; E2 `, j7 C' y2 W- b2 n
) L- R3 Q) p. Y) G2 x // 遍历 s 维护 intervals 和 allIntervals
9 Z, }+ L! i! D q- P1 H! }5 H int last = 0;
0 M1 [ z: q {- ?8 t) e for (int i = 1; i < s.length(); i++) {
0 [: Y/ e% I z1 w if (s.charAt(i) == s.charAt(last)) {, F$ ]6 D8 E! y2 O6 Z+ a
continue;( w+ _7 v, a8 E% Z2 |, J
}& g4 @2 W `9 p. K) |; r# u
Interval interval = new Interval(last, i - last, s.charAt(last));* n% K. U& O" F. S/ ]2 [
allIntervals.add(interval);
! a( Q& K1 r; p1 ^. s& U intervals.get(s.charAt(last)).add(interval);4 l0 z( d. i3 i* D9 @
last = i;
4 T) {7 {8 t& y- ^5 J }5 f) i* |+ _4 h0 E3 ]
Interval interval = new Interval(last, s.length() - last, s.charAt(last));
r& S3 p7 s' K$ y$ t1 x allIntervals.add(interval);5 }& A# P l/ C2 A
intervals.get(s.charAt(last)).add(interval);# _, |- K, o* M9 i
! N2 u( Y' [' t: I0 a
// 每次 query 调用 maintain 维护 intervals 和 allIntervals
. }9 Z0 X4 F0 A$ } int[] res = new int[queryIndices.length]; F# j) `. j9 ~" c
char[] arr = s.toCharArray();0 ?" t: Q/ ?1 O& p
for (int i = 0; i < queryIndices.length; i++) {
; K! N( E: m- q4 U+ T res[i] = maintain(arr, allIntervals, intervals, queryIndices[i] + 1, queryCharacters.charAt(i));- Z* M2 ^) ^( i9 E3 X
}
& @4 ~; G K% y( [0 h5 C, n4 I return res;4 _# w. e; a' @; F! d" v3 u
}
5 x7 I& p# p+ I, Y% Q! z3 g
9 m, }+ {9 u& | // 将 arr[idx] 替换为 c" T, Z! v' d$ ]# u
// 维护 allIntervals 和 intervals
1 D2 z" I' j, E# u; p // 返回单个字符的最长的子字符串长度
2 y+ c/ \& K- Z- v5 K private int maintain(char[] arr, TreeSet<Interval> allIntervals, Map<Character, TreeSet<Interval>> intervals, int idx, char c) {; a* k( O& M) G0 L
if (arr[idx] == c) {! T: X. L5 K* }2 W+ k9 ]3 f" q; u
return allIntervals.last().len;8 `+ [& n& B6 D* p
}
1 m* t3 S& x6 G+ u% @+ b
5 c! P0 e( L3 R; J( c) x. v9 K // 维护原字符 arr[idx] 的 interval
3 j" Z q/ q4 g4 i. d2 Q2 n var treeSet = intervals.get(arr[idx]);8 Z6 H7 U n4 q e
Interval origin = treeSet.floor(new Interval(idx, 0, arr[idx])); // 调用 treeSet.floor/ceiling 时,只需要 start 即可9 b$ a* b0 t; ]' P) A) J. {
treeSet.remove(origin);
# ~8 Q$ e; P1 U5 q% o, h9 ^ allIntervals.remove(origin);) j" q+ D$ [9 B: `3 Y4 H# S
if (origin.start < idx) {
- C" }: i) G# G' g Interval interval = new Interval(origin.start, idx - origin.start, arr[idx]);
) ]1 t6 g$ N7 c1 S/ o# J( Q" t/ E treeSet.add(interval);
$ P' n7 B: [8 O. \- e6 Z allIntervals.add(interval);. R. F: }8 M1 e/ t
}7 }3 n9 d* w# Q& `& Q# T8 q
if (idx + 1 < origin.start + origin.len) {
) j( p: }# _/ ~- X5 e Interval interval = new Interval(idx + 1, origin.start + origin.len - idx - 1, arr[idx]);5 c- w0 M( g! W, G$ {( s- e
treeSet.add(interval);
1 e8 ]& V% d# f6 }/ P' W. p allIntervals.add(interval);
" G, p. z2 V1 c4 Z E6 \ }" L" o, x' [ f, m# A W! p" B) K
U6 z# w" A1 x' q+ Z. c
// 维护新字符 c 的 interval. ^- Y) c8 M. l# \
treeSet = intervals.get(c);4 n1 J3 r8 ?' e
if (arr[idx - 1] == c && arr[idx + 1] == c) { // 左右连接9 @5 e& j% i- }' b
Interval left = treeSet.floor(new Interval(idx - 1, 0, c));. s: O5 k H' @
Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
4 E8 ]) G: z; a5 e. c treeSet.remove(left);, \' A+ A- B5 a4 X% j$ R' j
treeSet.remove(right);
1 D& _. U4 Z5 k6 S- v! j' O allIntervals.remove(left);
* {' E: R& V! o0 L allIntervals.remove(right);
( S! G) N1 {& ? o& Z Interval interval = new Interval(left.start, left.len + right.len + 1, c);4 R) l, T6 p1 w/ ~/ p* e/ ]: @
treeSet.add(interval);
/ t( l. q% Y' k. q; @ allIntervals.add(interval);5 X% N2 f2 W" P* H8 q$ Q7 ]
} else if (arr[idx - 1] == c && arr[idx + 1] != c) { // 左连接( b7 V7 s4 v/ }
Interval left = treeSet.floor(new Interval(idx - 1, 0, c));1 D) p" I3 \5 v) u& y- A
treeSet.remove(left);7 S y- z' y6 \1 M$ m$ C9 z) Z
allIntervals.remove(left);/ N- }$ n" H; Q3 R6 ]3 |$ g
Interval interval = new Interval(left.start, left.len + 1, c);+ h; x# }9 ]6 ? k M( `& E) n; B
treeSet.add(interval);
" v2 W- m& E" R3 _3 U allIntervals.add(interval);$ w$ C( `8 b! T; H
} else if (arr[idx - 1] != c && arr[idx + 1] == c) { // 右连接
% Y; h! R& g# z( t Interval right = treeSet.ceiling(new Interval(idx + 1, 0, c));
6 S9 A2 u/ W. I4 z9 f treeSet.remove(right);
( v& J: ~4 w; x$ O1 }( o allIntervals.remove(right);6 {0 k2 p! G+ _
Interval interval = new Interval(idx, right.len + 1, c);
, I0 |$ T+ Y9 O# y treeSet.add(interval); k- m% z. j6 j L% a
allIntervals.add(interval);
/ {( O9 u) I5 x6 I9 H" c R } else { // 单独一个
' ]: u6 S! Q. [1 J# }6 d" j; n9 W Interval interval = new Interval(idx, 1, c);
( s! q+ ?% z; U6 A, }( v1 X9 D0 A. c treeSet.add(interval);
; f: w: C) A, ?: C8 ?7 R allIntervals.add(interval);
( F. Z9 v f2 j7 }% t% Q* | }
) U) ~# n h4 m+ W, Y
% m* Q6 K: M1 ^! m9 I' ^ arr[idx] = c;/ i$ f4 z& R7 t }
return allIntervals.last().len;3 ~! K7 e' x* W5 @
}: U2 K+ o ?! F$ ?/ L) D/ Z5 P' h7 z
} |