No.1 人口最多的年份
9 n0 M/ G2 l: H3 _' O! P; x% s% i4 h. ?
解题思路0 [- ]- M; H0 i4 h% E7 f8 O
6 h( ~- t/ j4 H; U0 e1 o7 G6 q
数据范围比较小,直接枚举统计即可。
% R8 j$ Z, p' m7 i0 G, A
# b) ^; S8 x. m, L7 J1 ~代码展示* _8 V- ?! R4 e6 T0 P6 [
$ B) V: O4 u5 I; Q; [- class Solution {% V" s6 B6 E( x* i+ s5 o
- public int maximumPopulation(int[][] logs) {; ^+ L2 H& X' |0 u
- int[] population = new int[2051];( i6 C$ t: q, v# J5 y
- for (var log : logs) {/ I: r* @* a8 s; \& b
- for (int i = log[0]; i < log[1]; i++) {
% s% z8 O) ~5 l( a4 [: b - population++;
; G) R' }' A5 j - } }- N5 k& I6 T# J; f) f; N
- }
. H7 B& j7 _ G; o) y! X, m- [ - int res = 1950;( H. E8 @; C ?; N, |$ \3 p: \
- for (int i = 1951; i <= 2050; i++) {
* N! E" R9 @( N - if (population > population[res]) {
1 p5 }) H. X5 v3 L; I+ W5 D$ C0 k - res = i;
& Y2 b. H! |5 a5 F+ \$ ]1 x* s+ \: s - }
" R7 h) G3 Y: m7 U" \- u - }6 R- Z Z7 [1 U$ Y% s
- return res;' E9 [8 N' p" n$ T' ?2 q" y
- }% V/ D. ^7 a+ B. |
- }
复制代码
) ?4 ~, b. K6 r8 o
' `5 i! o9 n, }( f- b& j; ^No.2下标对中的最大距离: k/ d% L, F* p) N( U
0 h. P% \2 c8 `! c% w
解题思路" n B6 [6 @6 O+ V2 i
* l2 \- o' ~( ~3 q% O! `* W: R输入的两个数组都是单调的,可以使用双指针。0 l/ a2 Y: M7 e3 j6 G; l
& s2 l% H* {% q, k
代码展示2 {- h" o2 D' p
" A V2 w3 ~! Q+ q4 ?& T
- class Solution {
8 W, K3 T/ S; i$ Y: u( Z3 } - public int maxDistance(int[] nums1, int[] nums2) {4 I" d; Q/ T5 G" f& I, b
- int n = nums1.length, m = nums2.length;4 R4 r6 F9 a$ c
- int res = 0;
. N$ n- M$ }1 N5 S( ]* X; B1 y - for (int i = 0, j = -1; i < n; i++) {
2 m' [$ \1 F0 K( j. w! F - while (j + 1 < m && nums1 <= nums2[j + 1]) {
. f- F$ S4 s# [ - j++;
- B9 T/ Q+ U; n% l; H - }3 b* S7 X9 o/ I2 k9 w+ A% r
- res = Math.max(res, j - i);$ G+ T( P( I4 h
- }' w$ A% V8 g' f
- return res;% m) u# g, `# d9 Q% H
- }
% j' g1 l! X" ~+ y9 k5 W0 A - }
复制代码 0 f! |# T$ N$ @; i6 P7 X! W
No.3 子数组最小乘积的最大值
y+ ?% P' E/ w9 `2 ^) c% C0 ~/ P1 f$ q
解题思路* }: v, `# F- {3 [$ L
- V% @: U9 ~, E
单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。
# S( M: a j1 U5 u( v. ]* _) d4 H0 l7 q
当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。# a7 Q7 e7 q2 H- H' O
" p+ @) `! g* x! U+ L3 N
代码展示
" T7 j* s) F# D. I3 c# N6 R* u L& Y4 c! E4 N/ K' {
- class Solution {
5 M( i- S$ h" p! Z1 [1 a" R - public int maxSumMinProduct(int[] nums) {
6 l( b0 _5 H% T% g - int n = nums.length;% |; {! f* S6 f$ C/ k( `
- long[] preSum = new long[n + 1];
) f7 S0 Z3 r* \: ? | - for (int i = 1; i <= n; ++i) {
% M0 J- Z7 V- n - preSum = preSum[i - 1] + nums[i - 1];4 A* s) Q/ p7 O' U0 @
- }6 Y8 C+ a3 u* q) E
" I& G7 a0 L1 l9 [: Y8 Y- int[] l = new int[n];0 a# m8 ?+ T% G9 c
- int[] r = new int[n];2 a7 p$ V& l+ K G6 |
- Arrays.fill(r, n - 1);
: a1 p w% B: A- U) G% Q - 1 [* z7 p! w2 }5 Y; P C
- LinkedList<Integer> stack = new LinkedList<>();( @2 Y# A+ ~0 ?6 l
- for (int i = 0; i < n; i++) {3 \2 Z) u& U% B- B0 h
- while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {8 {2 M# s: X; Q' J" H0 W
- r[stack.pollFirst()] = i - 1;( u4 [; p8 w/ }% k2 Z P
- }% B+ F% T. e; u& n! y$ n3 t
- stack.addFirst(i);0 [. W* Z7 ~5 D4 Y- z
- }1 R& U$ r' t* L+ ?/ F9 _) x* ~
- stack = new LinkedList<>();
# }+ h7 l1 O; R$ O, a% o C - for (int i = n - 1; i >= 0; i--) {
0 `' W# ]) E; _# A1 c - while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
8 f; a0 E' h5 b% r% d6 { - l[stack.pollFirst()] = i + 1;
6 j3 I) a( T# b8 s - }
5 }& \* v$ g" W' Z! S7 q! Q# d* r c5 g - stack.addFirst(i);
7 q! p& E) c! |0 G+ u - }
6 I" J: v, }3 ]4 W% U - 4 x2 {* v/ W& g0 ?/ ~6 x
- long res = 0;' j. h" d5 F% R3 ~( f7 r
- for (int i = 0; i < n; i++) {6 o1 ?8 Z6 n3 b2 J& u5 p- I
- res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);/ a5 H* b9 c& P6 g% U6 @
- }
' ]5 J9 l: \ q$ a. ` - 1 [: q3 e( k. e! K! X8 Y6 ]
- return (int) (res % 1000000007L);
: o8 G9 J, s/ _! }# d M; t - }+ Y: V0 G$ L; P1 V! a, A! P
- }
复制代码 ' e) e7 d& k2 c& b d) H! L+ W5 w) f$ j
No.4 有向图中最大颜色值
/ g: `) P- w8 W+ w: h, ~
: q' F$ Z+ `) e; f' T/ ^: y5 J解题思路
. C( T# S" }! E! @& W. w; w# I0 W& W0 b: b, t
先判断图中是否有环,有环直接返回 -1." x+ ^! d8 P" `: Q- W5 b% K
1 B2 k4 D8 e7 |1 s3 \( M* t无环的话则使用动态规划求解。
, x6 @& q7 l+ t. X, Q& i6 ?6 d5 v: I6 h5 }( | X, L' Q
代码展示9 v3 c0 N# R! ^) ?" N9 P
. j2 o; N0 L4 n% C
- class Solution {
d5 ]% w% ]1 z# \5 o5 s3 g# M6 k - public int largestPathValue(String colors, int[][] edges) {- V" w$ _; `9 z. U% O
- // 建图
: X, Z$ Q* j1 J+ H - int n = colors.length();
# f. s" c& L2 K$ l1 J: O - Node[] nodes = new Node[n];
m4 `' y2 g S7 W* j, R% [7 d - for (int i = 0; i < n; i++) {
5 e2 T! l: |% V( r9 X' M* u - nodes = new Node();2 i2 @9 {/ _1 [; C" E4 M
- }" t8 l7 U" ]& A* l h# N
- for (int[] e : edges) {
: ?3 J: z) o% B( ?+ U6 j0 e - nodes[e[0]].nei.add(nodes[e[1]]);
, i9 D N. m0 j1 _' }( U/ o - }
4 y1 h$ v' I* v$ J# x$ j; T - // 判环2 D* r+ V4 Q1 M, y( z: n3 q. u. A
- for (Node node : nodes) {$ Q# l) ?* ~1 W) }; a" _. E/ m: w
- if (findCircle(node)) {) }# G# M1 X9 g- u8 Z
- return -1;
" I" L0 T( Z" G1 ? X& W - }- r7 l# D( O ~+ }2 h
- }+ y' u; [4 n7 A9 ~
- // 动态规划7 H/ f4 p( m4 ~( b
- int best = 0;( q& A5 }2 @- I d
- for (int i = 'a'; i <= 'z'; i++) {
$ m: ?! m9 K' X8 I - for (int j = 0; j < n; j++) {
T7 @- z0 q& v! b" c. ?2 P* Z( J - nodes[j].dp = -1;+ {+ }+ i" J f O- `9 B
- nodes[j].val = colors.charAt(j) == i ? 1 : 0;
: V3 Q$ V5 I. \ - }& n- i% H3 W M
- for (int j = 0; j < n; j++) {
1 x2 G4 w# a. [ e% S7 x$ W - best = Math.max(best, dp(nodes[j]));9 h. J% s8 F1 N0 \
- }0 C4 [( p6 V# }& t6 o
- }
3 G; g- {' T; w: a3 ~9 m - return best;
% v* W! G- ]5 j' I) M3 Z - }
8 N+ q3 a( z8 V0 ]+ @ F - . t0 Y" A( m) }( Y5 l) M# b
- public int dp(Node cur) {
! x0 h8 ?9 V; _1 m. s, C - if (cur.dp == -1) {
3 l) Y1 W; c/ F& s; [: ?; s, k& Z4 r - cur.dp = 0;( d/ m5 G% B9 l
- for (Node node : cur.nei) {/ x9 A( T1 o0 g# y$ H
- cur.dp = Math.max(cur.dp, dp(node));- q& U: [" t& i% A4 Y5 n9 o$ J" E
- }; y3 {0 r+ ]: _% N' F
- cur.dp += cur.val;
' I8 Z6 P! n+ z- _, i6 W8 S% ] - }
/ x1 b9 S; V) V D+ X5 T- R' V - return cur.dp;
% A* n5 E/ J$ `& X4 l - }
( d2 r6 [4 U7 Q) G0 W* u - 7 `9 N! p' |, z. C
- // 精简版的 Tarjan 算法:8 n# I! z1 ?! p) ?, \7 C
- // 仅用作判环,而无需求出强连通分量
. {4 k. P& {* ` - // 所以并不需要真正使用栈,只需要一个标志位即可
8 n% G& f2 l: [3 E2 R& | - boolean findCircle(Node cur) {$ E/ R* ^% b9 z) c
- if (cur.vis) {
. G2 q3 u/ x0 L' j C3 {5 f - return cur.stk;
5 Q4 o" y6 Y- F0 d - }
' m3 K: k; v% b; B$ p5 J - cur.vis = cur.stk = true;, A4 K( E$ H7 u2 z) G
- for (Node node : cur.nei) { N1 V# l# ^% Y3 ]( x: J c; @
- if (findCircle(node)) {
7 \9 B: v3 w% l7 b. ^; B- i - return true;
+ A* e6 V/ [! ^& X+ P. F) j1 v - }2 Z+ c/ t% o# g3 \
- }
3 v+ C. e6 S! p1 L% }8 i - cur.stk = false;
* [, O l. q+ {" l1 P6 h% u - return false;
& l+ o3 c' \8 f q' r. d0 K - }7 `8 [: H$ j' o, u- h" D
- }
$ i7 Q/ O1 j# A
" m& V0 [; [: e# B" ~1 E$ K2 M- class Node {
% o' q, `# ~3 T& ?8 h: W5 b; i - int val, dp; ~! p3 W7 U/ e
- boolean vis, stk;
% C1 K3 k [/ x - List<Node> nei;
/ h; I* ?5 J0 {; m+ `- v - , M" l8 _; D, M1 p! o# y
- Node() {" Q6 H; I; }; M. A5 @( V- `
- dp = -1;
0 H' G2 _6 Q; `1 a5 I$ ]1 z - nei = new ArrayList<>();
5 Y$ a; W- T F5 N0 ^. h - }
# G, e( j* B- X5 X. _ - }
复制代码
. a* l; j% C L& H5 d6 x4 D
' `' M( w1 Y& N* q5 c- Z2 R |