No.1 人口最多的年份
# V# G1 M V M7 `
) f6 `/ S- _( k2 K2 F解题思路
* N% Y: B d4 ]! @. `* X' }
9 t( ?/ ~- I5 Q1 r0 K1 C数据范围比较小,直接枚举统计即可。) X! I! y' S3 q; e4 U( f% [) f
% p! J9 g) k. Q$ d7 \5 m代码展示
* b! d3 C4 H; a) h- 4 L' C' [+ x, {1 F8 c
- class Solution {
( R- t* h" ]' r- h, i$ G$ @$ \ - public int maximumPopulation(int[][] logs) {
8 x' N- k' u5 X3 ?+ a - int[] population = new int[2051];! ?: ]2 Y' r, r. x _+ C9 Y
- for (var log : logs) {
2 N* g ], q1 y2 O% l$ U - for (int i = log[0]; i < log[1]; i++) {
0 n7 ~' f7 y) ]2 }" X - population++;
! s l6 P. D) f! s - }7 x+ M5 j; }' }/ f
- }# g0 E z7 Z( E1 r
- int res = 1950;
" f9 T, t) s! H/ P! [, F0 j - for (int i = 1951; i <= 2050; i++) {% p+ C: t) H7 Q6 ?
- if (population > population[res]) {
: n3 x7 n$ m) q- }; g - res = i;
% m3 v: H4 o9 ]* d3 e+ k - }9 Z8 F9 z( l$ H8 J% c- U$ z
- }
# ]% c( J, f# |5 V - return res;
/ Y/ P$ V$ [) {' ~ u# l - }$ s- l6 O% p' j; s) B
- }
复制代码 1 g* ], R2 G; i. k
; ]1 c; }2 m5 p, e& ]# i- a0 cNo.2下标对中的最大距离5 t. y) w2 `3 k( \. J0 K
6 s, R4 i' k1 u/ Y/ I
解题思路
0 J& T$ M9 O. R9 W! W0 `0 I6 ~9 t( ^$ K! s% D
输入的两个数组都是单调的,可以使用双指针。
x: ^$ G0 ?# F9 y8 \! y) ? J& l; | X) ^
代码展示
- l% U6 s! `( Q f1 y1 N- B' p! v Y2 _) T, q @, d! [
- class Solution {
! V$ |/ H9 K+ n0 p - public int maxDistance(int[] nums1, int[] nums2) {
* n4 K4 U6 F, L - int n = nums1.length, m = nums2.length;
0 X6 W& @! G5 k% {/ \' k. o6 g' m - int res = 0;
% b9 G3 V4 y, K4 j* | - for (int i = 0, j = -1; i < n; i++) { I% D7 U: j: t K
- while (j + 1 < m && nums1 <= nums2[j + 1]) { [$ `$ P6 B* ], F
- j++;
' g# w8 T- I- y! A- C7 N - }
" L7 x% L& k( H y' d8 M8 k - res = Math.max(res, j - i);
1 p! S6 N2 N$ ]( R C' j* G - }
: O8 ~/ j) I2 a5 E - return res;; w. ^' v; ?5 V7 ^: J0 {* `8 z
- }
& O0 M. C7 L0 z% n: U0 L7 { - }
复制代码 2 I6 J( h; W. V! V7 z1 t, I# S, |: b
No.3 子数组最小乘积的最大值, A; x4 }3 P( T- @# P/ J c
$ a0 w- Q O3 I
解题思路0 p& P/ p% a6 R8 d
8 @3 v: U; h* ]. i单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。
2 I; P6 ]: \% Z: D" B: D% F( H
+ `/ c. n2 e& {( X9 N+ ~当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。( |" {2 R- @# I* Y5 X+ w
: u8 _, d! E- U. J' U
代码展示4 v$ g. t0 f6 ~1 D( a6 H
6 E9 c8 [- l1 e" ]
- class Solution {
+ e6 V" Z6 H+ _. H& h - public int maxSumMinProduct(int[] nums) {9 U7 G; g9 E8 |- r) _9 g* r
- int n = nums.length;# G: E& v( I5 [# X) w( q
- long[] preSum = new long[n + 1];/ f" v! C& v/ O( x1 l" K# @; }/ r
- for (int i = 1; i <= n; ++i) {
5 J5 G! b5 W- ?5 a } - preSum = preSum[i - 1] + nums[i - 1];$ K Q' Z5 }0 X+ o0 ?& ?/ ~
- }
/ g. u; w( { ^: e0 a7 e1 S7 w
y2 K8 w2 t- D7 W( d9 ^# R- int[] l = new int[n];" b! [' p$ w8 i5 b1 L4 h4 q
- int[] r = new int[n];
4 D" X( _) ?( o+ h2 h: T9 g - Arrays.fill(r, n - 1); v4 c0 x3 o1 P
- 0 u! ]; i' h6 {( `9 O% |: X
- LinkedList<Integer> stack = new LinkedList<>();
1 l! \8 J Z' q+ k: e/ H1 q - for (int i = 0; i < n; i++) {
* R8 w+ S {# f9 Y - while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {1 w. P" P, P8 k7 g
- r[stack.pollFirst()] = i - 1;4 W) { c1 O; U0 n- c
- }
" N" I! E$ j5 N3 j& q2 f" }* R; W - stack.addFirst(i);
3 O4 t5 G- l& l6 }$ x5 j, F - }
7 V6 i5 a3 I8 V; e - stack = new LinkedList<>();4 p! C( |6 }8 I# ]6 A
- for (int i = n - 1; i >= 0; i--) {2 Z2 R, G2 l* ~) d( g/ B- \
- while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) { W0 A) S& ^6 b5 Q* T3 W& u
- l[stack.pollFirst()] = i + 1;( I7 X. M4 L7 v/ d* u. t f+ g
- }& {) o, g9 j; q+ k" }
- stack.addFirst(i);; U1 S# N' G2 _! T& S
- }. X5 ^0 V. ]1 F4 q
- ) ^ r* ]1 A' h; w: t. v
- long res = 0;
6 j3 Z C: P# b, x$ L( k - for (int i = 0; i < n; i++) {
/ W( K6 R* `4 r( H e) q - res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);( I+ R+ O' L4 K* c
- }. R0 ?8 U; p3 P8 ^
6 ^) z8 S. w5 v: c5 k- return (int) (res % 1000000007L);% g6 r: A5 y8 t
- }
# {- J P+ H" O - }
复制代码 ' S4 T/ p4 P6 H$ |, G/ J% X1 v- ?
No.4 有向图中最大颜色值* ]& N9 x0 u& `- R
7 W! q6 j* C3 z" N/ Q/ T3 j
解题思路
8 {+ D8 U" O6 M, S; i. R" Y; P* ^9 V2 |- x# _! x% d
先判断图中是否有环,有环直接返回 -1.
( `8 t) C( i9 r. k# W- L" f3 h4 ^$ s% s% H- O7 L
无环的话则使用动态规划求解。
C `6 x3 _; [7 M% x
' c! P$ b9 L6 x& g5 u5 D代码展示- P2 L: D, } U1 C3 _
; h- b: t' ]. w% z- class Solution {5 e- c7 e9 c# {" L+ `/ s
- public int largestPathValue(String colors, int[][] edges) {" x" t, z+ J5 L3 I; r& ~
- // 建图6 C: t* ~% N' h. t6 u! ]9 G
- int n = colors.length();1 v( X$ y2 g; m
- Node[] nodes = new Node[n];
7 |# Y T/ Q1 A - for (int i = 0; i < n; i++) {* V- V7 E! f6 X# q
- nodes = new Node();- T( _3 }' N* Z# n. V/ Q' c
- }6 D& X2 ~" b9 j9 ?
- for (int[] e : edges) {: @2 N$ C* W+ Y2 ]
- nodes[e[0]].nei.add(nodes[e[1]]);
, R& a" l( A+ L. l) M4 f1 D3 @8 r - }
7 A% e" U0 c2 q4 U# { - // 判环
: `% |% n: l: o5 M# u" ?5 d - for (Node node : nodes) {2 i% a. B1 O8 X7 O" E6 w, K
- if (findCircle(node)) {
, i! e" S* j( J' ^$ ?0 b - return -1;
" j6 Y5 H" a9 ]/ x1 c - }
! V8 ]: f6 ~( V( V% C* a( R - }
0 b( k; P% J( T0 T9 ~0 z - // 动态规划
* U+ R5 h# Q5 z' R# @3 Q, p - int best = 0;6 l/ c: A( v/ P* P
- for (int i = 'a'; i <= 'z'; i++) {8 p0 {) @! c0 \. N' s. G i
- for (int j = 0; j < n; j++) {6 O6 m+ q" @% g6 N
- nodes[j].dp = -1;0 K: q; {( M- x. a. ^
- nodes[j].val = colors.charAt(j) == i ? 1 : 0;+ ~+ _$ |% S5 g% w, t! b. `: g
- }+ ^9 k$ q: g- d4 p: g1 Y
- for (int j = 0; j < n; j++) {6 |, _; ]. y3 R- J$ E/ p' ^1 U& r$ f
- best = Math.max(best, dp(nodes[j]));, b# ^( I1 R- u$ b
- }6 E2 d$ p0 c# g" H6 r
- }/ g# ?; J8 Y; e0 i7 ?! F/ J( d
- return best;
) h. J" h5 f: P' y6 | F6 s - }
* t3 P+ R( t( T: T3 A9 h. B& B
' ]6 k0 n/ E, G1 W5 _$ W) |- public int dp(Node cur) {" \4 q# h3 F$ H$ d' _
- if (cur.dp == -1) {
' i. y# y5 b3 _* G - cur.dp = 0;
8 q( m' B+ E" N& C6 r2 o' M - for (Node node : cur.nei) {
( @* o7 M# m! H) N' @ - cur.dp = Math.max(cur.dp, dp(node));
j' B1 M+ O' c5 a4 [5 R7 _& F, e - }
/ _7 J& J9 f. k4 e) p - cur.dp += cur.val;# x# k" A, {, O
- }& M. T9 m# W$ a
- return cur.dp;/ @7 n' q0 Q( Y" q5 o+ X' o
- }
, A i3 ^4 R' k1 X" L# h' E
3 z3 U' q0 Z, J- // 精简版的 Tarjan 算法:. t, g# R7 P4 i- Z0 x
- // 仅用作判环,而无需求出强连通分量
, G" A, P/ }9 h' I8 `* n - // 所以并不需要真正使用栈,只需要一个标志位即可7 B6 |+ d+ K, S1 |, U+ ~! z
- boolean findCircle(Node cur) {
. x% c+ G5 L1 \# P - if (cur.vis) {
3 h+ ~! [9 e) ?# l }' a3 R g - return cur.stk;
7 f3 r; N+ A0 S+ c: n - }7 R" B$ V2 ]+ N+ @0 b& Q$ T
- cur.vis = cur.stk = true;
( P4 C0 f' M7 R# {7 D. M& N - for (Node node : cur.nei) {# v/ U& n/ x* }: U
- if (findCircle(node)) {
8 u) x4 w2 Z( K3 a- V1 m. } - return true;
h4 r6 Y) @! K; x5 f2 h8 J - }
6 |; J7 B( j1 O1 D; @- O( O% v - }
- Z; K8 C! f- V, d& M) c9 }; \4 T - cur.stk = false;
: A0 e; V8 `( S# p& J A3 a/ \ - return false;
" o; U) P @0 G. {7 ^$ o - }; t$ h; r9 v" [# r% F
- }6 E0 O) D2 E# Y) Y7 B
" `* k* {; K9 B. E- class Node {8 w- k2 z0 }9 a% d/ f% u+ A
- int val, dp;/ R1 w+ B8 z& u* a3 G! C, \3 ^ @
- boolean vis, stk;
- ^$ Q+ X" k1 a% |& V7 c - List<Node> nei;
$ O1 G. W, l2 L# u: @3 J - ) r1 m& C& @& l0 |9 A5 [
- Node() {1 [9 b! T6 s" e: o. u. \) v
- dp = -1;
" V6 l7 e& H9 w& k# N6 ~ - nei = new ArrayList<>();' D8 s: p% l+ M' n" w
- }3 S& E, ~1 A8 M! z2 H- Y& i# g& D
- }
复制代码
2 M% D$ b5 f3 \) }; K
8 a. I: ^1 r5 {5 p( t |