No.1 人口最多的年份5 Z/ Y5 O# g9 }
. j4 E5 y. J) y, h( \% G解题思路# o; m$ n$ V" O9 [" b+ H
2 F7 R. q4 N0 w ]- S
数据范围比较小,直接枚举统计即可。
. b) j$ U2 d% b
% m+ h- x6 A8 M+ e: F5 Y9 i代码展示5 }7 T' l& s9 u
' D) ]8 Z0 M7 M* f$ \$ ^3 L- class Solution {7 j0 z. F" ], Q( i5 _! `
- public int maximumPopulation(int[][] logs) {
; \) V; Y# T, G: r - int[] population = new int[2051];
; O9 F$ D, B/ D( r# U5 N u4 N - for (var log : logs) {
; j7 C) j+ K9 G2 {! r - for (int i = log[0]; i < log[1]; i++) {
# r/ Y0 q; I, O+ V" a/ L Q- e# q* T - population++;
" u+ o$ f0 |/ ^$ E5 `; a - }% M' r: S. g2 k6 O" j& ^( q
- }' G3 k: K$ `( g! u9 [
- int res = 1950;
3 M; I! r- I" J: A: |3 { - for (int i = 1951; i <= 2050; i++) {3 m8 m7 f6 ]: U, B% S+ ?
- if (population > population[res]) {; k i9 W/ _$ g4 Z0 q% @5 ^
- res = i;! h2 K3 K5 S+ q2 F% M5 \5 ~
- }/ Z, V# ?9 V. |1 D4 ?' u
- }$ d, N: ^: J+ [4 e y0 p
- return res;+ P3 r8 m3 V8 L$ E# x5 y( v
- }- i# b3 Y8 R* _; m, w* u! U) \
- }
复制代码
1 ?/ K. k9 `9 o6 I! D7 |+ H$ z& L# c- _. s% X0 G2 h" s t
No.2下标对中的最大距离; J- N' V. X0 @$ G7 x
& q, b) C+ A$ {( `/ [) e3 Z解题思路
& i: S8 D+ y) \( {0 x
2 @4 O) M5 r# U5 [! v* I. t+ L输入的两个数组都是单调的,可以使用双指针。' s2 j/ P# Z+ g9 m$ R& Z4 l( k9 c
3 {/ F6 t/ \4 X& z$ c2 r1 i
代码展示 Z) M3 V" r3 ]7 X5 Z6 H! ~
t7 v. {" f; K# j/ O0 Q
- class Solution {9 t7 Q2 n. \: J7 G+ U
- public int maxDistance(int[] nums1, int[] nums2) {6 L) m; ~3 r2 |
- int n = nums1.length, m = nums2.length;; X& p `. Z9 `, i8 i/ ?. O
- int res = 0;
; ]8 H' q/ J' K& _ - for (int i = 0, j = -1; i < n; i++) {+ v9 m" C! I8 p: U2 ^6 ^
- while (j + 1 < m && nums1 <= nums2[j + 1]) {
- h: p& g( c t0 g# j% Z, w2 o - j++;
' }3 c8 Y) u& T n - }
9 J {- G, d$ M) O+ T - res = Math.max(res, j - i);
: m$ r. i4 d" R5 X# y - }
$ M2 P2 Y- ~& G - return res;
1 X" @0 ~0 \8 F7 ^+ _ - }! B0 }* F; M2 c& g* |( I
- }
复制代码
+ Q4 k1 k# \1 P+ N9 N+ D/ a: CNo.3 子数组最小乘积的最大值; S$ O# W. J; y% O1 e- z
/ y! Q8 g) e3 i2 v) ]7 Z解题思路
: w# p1 I* E, ^- s- j. B
, Z" S* d' R# b; G$ Q1 N, b8 \5 J+ U# g单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。
6 E9 {7 T6 }0 j$ w! t7 f4 ^% t/ O+ a4 j- u
当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。
5 _8 |$ }8 B$ q) @ X9 i3 j3 p! G6 @% S, ?+ z& a0 ~' r9 \; b
代码展示4 b3 g: ^2 I! W5 `2 J9 X
$ J$ S* a" }( R3 ]- R
- class Solution {- r2 X/ t4 z: l- {" F
- public int maxSumMinProduct(int[] nums) {# f' [' S/ P- U u& K% m
- int n = nums.length;+ d1 ], k$ m' b
- long[] preSum = new long[n + 1];
- R/ e6 q0 j" h - for (int i = 1; i <= n; ++i) {
, O$ m( ^6 u% y% d4 H- f3 @% ? - preSum = preSum[i - 1] + nums[i - 1];
5 L: H: w7 o0 f' ]: O+ a. _ - }
1 z, t; a# l: K9 a6 p - * J7 X+ |' J. J" Z0 ^9 G2 T
- int[] l = new int[n];
) f% ]& \0 f! |. H" T( m- O) s - int[] r = new int[n];
n) _. _/ B! r - Arrays.fill(r, n - 1);; ^4 @% r# O" z% p7 C6 L, m
- 1 P) y2 F( D: Y
- LinkedList<Integer> stack = new LinkedList<>();. I; V& t/ E6 U4 O- z# l
- for (int i = 0; i < n; i++) {" M4 U' Q- r b& D8 f" R
- while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
+ V5 D1 P: u& E. ~ - r[stack.pollFirst()] = i - 1;% z6 `3 k& V& o, |- {1 ~: s
- }- y- u$ J9 r3 e6 F
- stack.addFirst(i); C# g9 b8 A$ Y K/ Y9 N2 F! R$ Y
- }8 q9 s( u& f) H$ q/ t9 N& J6 M
- stack = new LinkedList<>(); |2 D7 Q% }0 b8 F0 D
- for (int i = n - 1; i >= 0; i--) {1 M0 r- A3 C3 Y# @
- while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
. Y c7 x! N8 H - l[stack.pollFirst()] = i + 1;' U4 s8 u8 N" @1 H5 F
- }/ ], ?8 S$ V( I" Q
- stack.addFirst(i);
5 U) j. j' w. }) c - }
: g; a: R* [ ]1 K( F - {7 c1 R& g9 C+ U% C" e
- long res = 0;6 d# `1 b4 u8 e! p0 k% U5 _
- for (int i = 0; i < n; i++) {
% {, j! `8 b3 N5 }3 [ - res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
! o9 [1 `6 n: N2 |3 w9 n, R - }" m' Q3 R( J9 E$ o; b# g
- % e6 }6 D: m+ }& i0 M) X
- return (int) (res % 1000000007L);
l0 X% I! L k# n& x% v2 v) O+ U - }
' t$ a1 ~2 E) D6 s9 p& I - }
复制代码
$ @$ f( q/ q; t C9 zNo.4 有向图中最大颜色值: ?# t' ~. Q; H+ A3 {
# f+ F4 G* j) i% a% K) m
解题思路
* [$ t1 |; q+ n) L( t
9 L& T8 R2 C( ~. B( U4 H先判断图中是否有环,有环直接返回 -1.
0 _+ v: E' |/ V6 v
; a2 }9 z- g: y0 x) `无环的话则使用动态规划求解。1 j4 \& I$ I, c
8 U) a3 a3 G4 `代码展示6 G# X b5 e7 Q. A
; v \7 ^+ F+ W
- class Solution {3 y' K; R: ~0 F* V, p# M
- public int largestPathValue(String colors, int[][] edges) {
" w% c& p; f& ~# a# y) N/ i - // 建图! j0 v, E* ?8 I3 y, V* h# m
- int n = colors.length();
4 W5 ~" p, W P$ T( @' y - Node[] nodes = new Node[n];
2 H, Y: S" }/ U5 l3 B/ U - for (int i = 0; i < n; i++) {4 [* F) U$ m4 ?) a( F
- nodes = new Node();: P/ [. ^) X: e0 Q5 B# Q
- }$ o" J$ H; }/ x9 l* B5 t
- for (int[] e : edges) {
7 ?8 H; G1 \! y0 k - nodes[e[0]].nei.add(nodes[e[1]]);: @! |! l* w) Y# H7 Y1 m7 s2 d
- }0 a0 {1 j$ c$ P, z7 c) ~2 l
- // 判环
: w" c% y' h# \" q" f5 m) O, X0 \ - for (Node node : nodes) {: k; `) _/ F N+ ?1 G8 r% V8 A
- if (findCircle(node)) {# U+ V% P- e. E
- return -1;' B* _0 F* x3 j/ P
- }
8 p) h) F/ W! M+ b - }
. D# a) C3 F2 s+ r1 C4 J - // 动态规划* z" b/ v' w. t) N$ |" u
- int best = 0;
8 i* ]: G* J& B# @ - for (int i = 'a'; i <= 'z'; i++) {
a! r- N5 t, j4 U- i7 [ - for (int j = 0; j < n; j++) {8 M$ r3 i4 O2 `8 X
- nodes[j].dp = -1;4 p3 _9 T- @% V
- nodes[j].val = colors.charAt(j) == i ? 1 : 0;
+ Y! ^. l# K5 Q9 ^, i3 ]2 V - } Y7 S/ M) o9 T2 E% Y0 D
- for (int j = 0; j < n; j++) {
2 @1 }5 p# u3 ]7 M* X% j6 H - best = Math.max(best, dp(nodes[j]));& C4 Z6 d8 ]% @/ \6 i
- }
& G0 Q% k6 ^! q" ?* |2 j - }. q. n Y5 u! n& y3 o0 ]9 \, R
- return best;
% G7 j: p! b0 U0 W, _5 N. K - }! M3 X0 m+ s0 V# l6 d* }
7 W) t. o& w, E% U# A- public int dp(Node cur) {
t& {5 k# ?( m8 j0 D - if (cur.dp == -1) {
& J) B, M# |+ X' Q% q8 B* P - cur.dp = 0;
" p$ c# n" V! X, N4 @ - for (Node node : cur.nei) {3 _- V$ `# Y0 n1 p( r
- cur.dp = Math.max(cur.dp, dp(node));% N6 l! S0 @ ?3 }: P
- }
- _) ?8 ^+ ], x! }# G! O. n - cur.dp += cur.val;. Z* t5 h; s4 ?7 F
- }! Y0 W6 L4 X" ~% f) L
- return cur.dp;+ x4 l* H( E. E0 w
- }& z- Z5 k" L* ~% |4 W
% Y% |3 L0 c; a- Q& _- // 精简版的 Tarjan 算法:
- a2 v" Y6 ] m. t2 A$ S: [ - // 仅用作判环,而无需求出强连通分量7 q: D) m# ~, L+ W
- // 所以并不需要真正使用栈,只需要一个标志位即可% G# ?% c) v, O; l0 d) u
- boolean findCircle(Node cur) {+ V0 G+ C- E* V' B, D' c0 {
- if (cur.vis) {$ m& {; m8 M9 W5 o
- return cur.stk;3 ~- }, E0 u* E. i. P0 M' |
- }
+ N. b' ^ N% ~* I - cur.vis = cur.stk = true;2 m% [* Y6 f5 R
- for (Node node : cur.nei) {! _6 f' S7 i% n& g
- if (findCircle(node)) {( F: I8 v V2 s" U' b& X2 F) p
- return true;, n. m( l+ S: l8 y
- }
f0 R; o# E4 t2 ] T - }
2 S8 ?/ C8 M+ T3 y8 [/ C - cur.stk = false;
- I9 E; D: [' r/ W - return false;5 }0 \% e8 ^- G7 k! N
- }
5 k# y* P9 Z$ t6 ^! z - }
" U$ ?. n% c+ m* e9 M
3 ~( H, \; f+ z# @; } m- class Node {
3 f3 l& g) N; Q+ i/ X - int val, dp;
/ B& f- t. y) [1 d6 L - boolean vis, stk;( T1 _7 ?0 O a4 t
- List<Node> nei;* b' Y8 R0 ]9 P! m$ x
9 j Y( B$ g, Q( b2 `$ d5 e& g. |* L$ G: k- Node() {
2 w3 [% Z8 C" w5 D& i# I - dp = -1;
6 G- Z/ z9 Y& o4 |, L' L - nei = new ArrayList<>();* k$ m0 R. ]5 S* X2 I
- }$ q5 Z7 r" b& X2 b; A
- }
复制代码
, t6 U# r F7 c9 V4 R- H: V/ X0 O: ?/ {; ]4 @
|