No.1 人口最多的年份
; I- n) @3 G9 H3 m8 C) v z( _- Z' l( l
解题思路) Y$ z$ B, [: O- R" ^, N) ]
- g1 k3 \( { X5 _ i* I0 f1 j3 L
数据范围比较小,直接枚举统计即可。
( V1 }2 W, {% u; w$ `
7 b- d! F* a( d, N1 F& v& E代码展示
F$ R9 u! C0 q$ A6 j) e* `- 5 Z$ R) M6 n. j( m
- class Solution {# p b$ v- ]+ h
- public int maximumPopulation(int[][] logs) {4 [" A6 _% x; q% i3 m- z
- int[] population = new int[2051];
: s& x8 j# G4 u/ t4 ~2 i* Q - for (var log : logs) {1 E* K6 [$ O1 `& d k; P) f- N+ d
- for (int i = log[0]; i < log[1]; i++) {
X. v* c* \" `: B% B" f) }: d - population++;
: O9 K& \1 ` o% w$ T4 X& w - }& f; S1 P! T' v0 g
- }# H; [- t1 B7 |3 f" N8 O8 E8 ~
- int res = 1950;
0 Q& s: I7 }* B& |* o: ~6 P - for (int i = 1951; i <= 2050; i++) {# E& V: q5 s6 }% O4 I4 }+ w. \
- if (population > population[res]) {- o* Z/ V- E, C; T5 m
- res = i;/ s N. x5 N& o- k: P- k% T
- }
* j, q& g$ d- r9 y |" @) M - }+ K3 x/ F5 O' f8 z" [/ Q2 R C3 L) q
- return res;7 L7 z3 G# p S& m3 g5 ?: u
- }' r X0 \: H8 j0 u9 a8 Z, h
- }
复制代码 " q3 ]. j B" q3 j; ~/ @
. z/ u% J7 _- E' n4 l& K
No.2下标对中的最大距离
& q( I" ?# F: u; e7 R9 f% `- T8 E. Y3 i& l* Y( j9 H
解题思路
: l& k$ \4 F; D9 `' |; f
# Z( S2 a" k' f输入的两个数组都是单调的,可以使用双指针。" b5 E; T( U0 ?3 A
8 v% E w; }/ `& d* Y. P1 F" w代码展示
( V% N% m) t- D0 f* Z6 N+ f5 }+ l
- class Solution {/ J) Y9 b/ x6 c/ s8 {$ O
- public int maxDistance(int[] nums1, int[] nums2) {
. f+ r* y6 B7 i - int n = nums1.length, m = nums2.length;7 ~. U$ _6 L) Y) _5 F2 d
- int res = 0;- f+ z1 N7 T7 Y, z; S: g7 V/ o
- for (int i = 0, j = -1; i < n; i++) {
1 G/ `& _- @' j+ n$ b' U - while (j + 1 < m && nums1 <= nums2[j + 1]) {
& `+ V, B* Y6 ^$ B - j++;, \3 o: `9 C5 ]1 b$ n2 ?
- }6 r7 s% \0 e+ s5 Y- Y/ E6 k5 T
- res = Math.max(res, j - i);
8 N+ H, C8 B5 k - }+ |2 e! r6 W% h) @' o$ D# b
- return res;
1 L: @( w5 @6 R' P! a8 f0 D - }, k' J9 O% r$ y# d5 ?
- }
复制代码 % {' X% X- {' X- ?' W/ i
No.3 子数组最小乘积的最大值
& k% Z; `+ F6 f U# m
; e* s' `) [. H+ d; C解题思路
3 n5 A- u+ ?2 C6 a D [; P( o
8 r( X9 K+ V: ?3 L$ |+ V0 N单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。3 J3 c% C- W1 }0 ]
3 H% v; d9 i* j- h) J) y当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。2 d5 f) l% D# h: ^6 j- u6 H c0 g; I
- ?- r6 T, E N/ R& U& N M- i; m代码展示
, C8 k0 P$ F1 s- l9 q* z w# c) H; Z8 m0 @% h2 I2 ~
- class Solution {7 X% R' u9 |$ o; d6 I" l
- public int maxSumMinProduct(int[] nums) {
& Z% N _7 T! W$ P& L2 `! W- Z2 a! p - int n = nums.length;
. v7 v; A( k* O5 G0 \+ o - long[] preSum = new long[n + 1];
0 e* Z& R Z, t, Q2 J* P - for (int i = 1; i <= n; ++i) {) [; w& b' d% ^0 }) }7 u
- preSum = preSum[i - 1] + nums[i - 1];$ l4 k4 c( b. U: R) `2 E
- }
# ~# h5 G! i' @- z - / i o* F/ t& m: a; A
- int[] l = new int[n];5 B. t9 {) P* |3 [1 ^: m( _( o" Y
- int[] r = new int[n];3 L. S3 \' O( P. `/ P2 J
- Arrays.fill(r, n - 1);
7 \7 h( Q% V) l3 u& Q7 {" r - 0 V9 }6 g$ Q: U2 D2 n
- LinkedList<Integer> stack = new LinkedList<>();
' l; T5 e3 o$ M' z- u - for (int i = 0; i < n; i++) {
& `6 ^! z/ F; [. e/ v& R0 ^/ y8 L - while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
! `) b( N2 G' L0 r4 S9 x5 A - r[stack.pollFirst()] = i - 1;
0 i5 B' Z( c" E% L- m4 B1 |- X - }2 a6 l$ Z% J: D/ c7 S- r
- stack.addFirst(i);+ L0 J2 ^" r% P% c/ I& l1 N
- }3 }" w% u1 h- f4 |- F( h4 @# K2 X
- stack = new LinkedList<>();% f: p8 _: }9 v4 @; T
- for (int i = n - 1; i >= 0; i--) {+ Z/ ?) ?, l/ ]5 \: |% r' e
- while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {" ^5 z7 d* N1 }: o; O" ~- C
- l[stack.pollFirst()] = i + 1;
1 P4 N; x/ Q3 ~! R5 i; p( L - }
2 L9 |( f+ ]" S - stack.addFirst(i);- @, R8 z0 X A6 m
- }
7 A8 X2 |/ q) L- e
2 L. t* D* W6 v! j- long res = 0;
# y T2 D* H1 ?7 d - for (int i = 0; i < n; i++) { x! G8 d( |' n( B+ Z
- res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
7 J# K7 S2 C$ q6 Z; Q - }9 y0 u. s* Z; E+ L0 O3 d1 u
+ G7 k9 d& Z j4 T- return (int) (res % 1000000007L);+ j0 s# K4 T3 ]# X
- }% G4 F! s# W# U P' o5 T. y
- }
复制代码 2 {5 Y' [8 r/ c$ [
No.4 有向图中最大颜色值
- Q. u9 e/ M1 }7 x4 I% D. z/ e p. `2 D( t) W
解题思路9 o/ w$ y1 E, `5 r
% c% j3 r% k; \
先判断图中是否有环,有环直接返回 -1. ]7 w7 f* G- \$ Z' V3 ~, |
8 F1 V6 [0 D; Z0 S
无环的话则使用动态规划求解。
; k9 F! g9 `( Z! F6 T8 F) q6 ?& ?
代码展示: G u2 d" k% A4 _3 I, ~) s' r
V6 W/ x- M9 c1 ?- class Solution {
. T- K! U/ R R Y+ { - public int largestPathValue(String colors, int[][] edges) {$ d/ z" s8 E+ F/ m8 A
- // 建图1 U# y$ M( M0 B1 @% J
- int n = colors.length();
, d: T7 `; o5 B' E - Node[] nodes = new Node[n]; P7 g0 Y; d; n ~0 w) C
- for (int i = 0; i < n; i++) {7 o s) w, o, q
- nodes = new Node();
9 Z2 M2 w7 ]* L/ M: l8 G9 T+ y - }' F8 M0 S; |3 R c/ g
- for (int[] e : edges) {" K+ v8 `$ c) V8 _$ m; o( R
- nodes[e[0]].nei.add(nodes[e[1]]);
, G) {. a0 a u. i - }1 H* p' D z, k9 C; H
- // 判环
! a7 n2 F/ M2 T' u - for (Node node : nodes) {
* s7 t1 C7 j1 E) q - if (findCircle(node)) {+ \% ~7 D5 ?, N2 w! a
- return -1;" D. H$ A* Y" s3 V1 L/ Q. W
- }) ^+ q7 L0 e4 m% ?5 k2 m; W% B" U
- }0 Y; W1 w/ T& T% k" v) Q, m
- // 动态规划
3 Z7 E |5 k- b2 Z# O# p - int best = 0;
% c1 J6 i+ x3 \+ Z0 \4 |# `4 a - for (int i = 'a'; i <= 'z'; i++) {
- ?' s, @0 e# C" s2 P! F( B/ C - for (int j = 0; j < n; j++) {4 I/ V. J7 s2 W3 v: s, k
- nodes[j].dp = -1;
" L# b# L4 M' u0 b- g( H7 i - nodes[j].val = colors.charAt(j) == i ? 1 : 0;+ i6 ~8 t! P6 Z, d
- } ^8 `4 K2 n& O
- for (int j = 0; j < n; j++) {
% ~5 d9 W% ?. ~ - best = Math.max(best, dp(nodes[j]));$ |0 ^2 ?$ ?3 G5 ]8 G; f
- }
3 R" Y+ G2 s- [' c9 @3 J( S0 I! } - }
& w$ q/ H" P6 r9 ~ - return best;. D% c" R. U5 t7 f4 a% H$ f
- }
! n% h8 ^/ H$ U; R4 h- E
. c; F% i6 K# ]* Y- public int dp(Node cur) {
4 I1 P0 E; u8 n9 d# b8 R( a - if (cur.dp == -1) {/ L. t, h: ?2 G+ G
- cur.dp = 0;1 Y/ N. j/ Z) m' r; d4 m
- for (Node node : cur.nei) {
4 b4 u, M6 {0 G s - cur.dp = Math.max(cur.dp, dp(node));
8 ~! G5 R; ?0 P S; m2 [4 Q - }
, {' l# u: h* m; A - cur.dp += cur.val;
: D8 W. l4 }! T4 W+ K9 Y - }& s* [3 W8 O s- i
- return cur.dp;
3 e/ r8 S5 I! `* U, l8 | - }
, i, }) X, d' k2 Z - 8 X8 s- n1 j& ~2 e2 @1 j l5 A" E
- // 精简版的 Tarjan 算法:
' ^( ?; S1 D4 t; w& W% K, h - // 仅用作判环,而无需求出强连通分量
- i3 v; O. {: \+ f - // 所以并不需要真正使用栈,只需要一个标志位即可
* W" U. B m4 A+ b8 k4 Q! c+ [ - boolean findCircle(Node cur) {
' K! }' Q8 j0 O: V! c - if (cur.vis) {$ o8 T$ x+ g" z, v: D
- return cur.stk;* a6 r! e+ U; v* s
- }
& v" B; a+ a& r7 a - cur.vis = cur.stk = true;' }& o# l1 a8 w% ?
- for (Node node : cur.nei) {/ ]" ?$ W# j4 \; W3 D
- if (findCircle(node)) {0 K/ `4 |. A. c/ p2 F
- return true;! F' P! b$ N3 `/ V0 l
- }5 q! l" L% e. q( r' z
- }
& w X" K0 ?; g# [ - cur.stk = false;
+ ~( U4 K5 d6 y* Y. O5 K& [; n" x - return false;/ z" l. k1 P9 g- B: s
- }
, R/ q7 G! |" ~6 d - }
7 d4 b1 R5 w1 e Q5 d* x- t" e" q - 8 H- _9 E7 x v0 K: A8 g( c
- class Node {. y5 I+ x+ ?5 e3 K! y
- int val, dp;
, q& @6 X. Z/ I# M; e- i# K& h - boolean vis, stk;2 d1 [* o2 M) S% S- Y7 W
- List<Node> nei;
6 n9 o: y2 P* p5 y, J" F
4 G4 W2 U1 s! F Z+ s! N( ^5 y: h+ e- Node() {
+ W1 z( |+ C0 ~ - dp = -1;
6 O% {6 X( W: t- b - nei = new ArrayList<>();# q* H8 D3 U- w6 t* t0 ?
- }
' W+ u1 k* ?0 j4 S - }
复制代码 " ]2 T4 E( @1 h+ ], N
0 ^% y( R; D& Y- q7 Q+ m" Q4 b
|