No.1 人口最多的年份
& b7 g, R9 c, E/ O3 Q( |$ K% P$ J/ b4 M1 `2 |
解题思路
- p) G4 G0 H. C( t' v& u7 O5 }5 q! e4 j/ z1 M! a
数据范围比较小,直接枚举统计即可。
, o1 H0 j5 V0 n. j2 n' C3 K
( W0 f5 J6 u; z$ M代码展示
% _' a6 z# L% u! \- $ B, t8 O7 |& F6 f- d# z Y* u- |
- class Solution {
^2 @. v' O2 ]$ u4 j3 z. g - public int maximumPopulation(int[][] logs) {
( t3 o V6 N! n+ {1 ~9 G - int[] population = new int[2051];
* W. {6 K* O+ q6 d. u4 T& A - for (var log : logs) {
# Y7 E. o8 c* z% ]3 Q2 P% o* x! N4 Q - for (int i = log[0]; i < log[1]; i++) {* I2 p9 E I8 g( A
- population++;
; Q( N; U8 X/ _ - }+ a- A4 C' s1 Y, W7 b+ ?
- }
/ T- q* i: ?( \; f - int res = 1950;, ~, [! N3 f+ Z; d& {
- for (int i = 1951; i <= 2050; i++) {: V u6 J+ h F
- if (population > population[res]) {
4 v# J1 a) k! x; E( X - res = i;
, ~0 }/ F# z8 W* \) A \0 n( m2 r - }; L9 v% }: I5 f8 ?, X# b4 J5 ^4 N
- }
8 z2 `- W! d, m" v* \( c - return res;
9 A, g: d8 G8 Y( v - }
. V# q( j# B+ k) w, J$ \ - }
复制代码 , r1 p5 [3 ?6 A/ q5 x7 V
) z, a5 @4 H. z% a- fNo.2下标对中的最大距离8 L0 V# a1 |( l' [5 k }; m
) `. u4 Q* ]" S- I% S2 R& [
解题思路
8 T" a: ]4 O+ U. J( D1 Z6 J1 ?
# Q* L0 x) p4 \9 i输入的两个数组都是单调的,可以使用双指针。% C7 g7 n7 q5 O' z
}/ w. f+ G( H; B; b3 `0 f
代码展示" t x" w _! e7 t+ Q5 Q" q6 l
& @/ R3 y3 v# a
- class Solution {, K4 |4 i1 N: p( y8 y% d# t: d, ^
- public int maxDistance(int[] nums1, int[] nums2) {
9 Q1 {+ u5 ~9 }6 x - int n = nums1.length, m = nums2.length;, u# R# |3 v- y, s: k
- int res = 0;
o( N- z f+ e+ O - for (int i = 0, j = -1; i < n; i++) {
, l, a6 o. u3 b - while (j + 1 < m && nums1 <= nums2[j + 1]) {
: d1 L1 @ v* N. l - j++;
7 c. j- c! ?+ ^ c+ e - }
$ z/ D) Q9 b T6 j - res = Math.max(res, j - i);
0 p+ s( u" V+ K - }7 f( N5 H9 ~' X# D. t F
- return res;) ~& ~5 g. D: M5 I9 J' `0 u
- }
' r3 O. c% R& [. q - }
复制代码
. @9 H6 P. E+ ^4 X$ ^# u oNo.3 子数组最小乘积的最大值
% M6 | W) F7 p" @4 N/ V( d, H0 l" y# a/ o. I; w+ @
解题思路% t. a7 p; D: H
6 } h) B, X( l' }* A$ F j6 R3 n
单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。
' n% S! t6 h2 y% ~
7 H1 S( t0 @% q" t2 z当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。2 e M/ Q3 k, N( b; {5 T
, ]& U; o( ^1 x- W) y& |0 t. `代码展示% l! B( J5 K+ z4 R3 [
, L" G9 q3 Q: r# p/ v" U+ x6 B
- class Solution {
9 X t6 U$ n" b" h- u! d - public int maxSumMinProduct(int[] nums) {
3 c* J! y& \% ]7 }. s - int n = nums.length;- ?& \% G9 {8 D4 M, X) s9 Z& R
- long[] preSum = new long[n + 1];
6 E. m4 r1 V. F - for (int i = 1; i <= n; ++i) {# b1 p% L8 V. ?! ]4 Y/ i
- preSum = preSum[i - 1] + nums[i - 1];" P5 \" w9 [$ e. X0 x/ {7 L1 U
- }
( J0 n' U' C. X8 x) Y - ! {, l5 k) h3 B6 |3 g
- int[] l = new int[n];
1 m+ g- s( ?0 g - int[] r = new int[n];
( {; m8 t0 c4 Q! c3 L3 q! x - Arrays.fill(r, n - 1);+ E& @3 d+ ^2 e5 E
" Q' C3 V* F4 Z0 H- LinkedList<Integer> stack = new LinkedList<>();
$ G* ?4 o0 r, p( L% W/ ~7 ]( Q2 U4 j" Z - for (int i = 0; i < n; i++) {
( }, T* j1 C$ z! w" ?- P$ b - while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {/ k" ?" T/ {8 i$ ?) R% ?
- r[stack.pollFirst()] = i - 1;$ j' v2 s. H/ M* @& x! I
- }% L0 w0 U+ \7 j* [; u% Z4 y9 X
- stack.addFirst(i); u- s) i% v- ]" T1 h
- }7 M- x3 i3 R% S
- stack = new LinkedList<>();
% ~8 c) s% Z! U9 r1 Z - for (int i = n - 1; i >= 0; i--) {
$ G1 R/ |3 w& J) b! }! ]) c - while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {' s# m; q/ v8 t! L+ b$ I
- l[stack.pollFirst()] = i + 1; L. s0 g: @* }% x; n2 ^
- }( ?$ E w; Y; X( V; n
- stack.addFirst(i);$ k' H" p( ^3 b1 L: g, T% h4 @
- }, B# L- b7 d: h2 ]+ O7 |2 U6 [9 I
- # ~& W; g5 q6 C$ `5 X
- long res = 0;1 t& ^1 ^5 N3 [3 y8 w
- for (int i = 0; i < n; i++) {: y. u2 B1 M& u; B" _! t% E
- res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
/ [5 d- S6 T8 Y. t& M - }% T" J% _1 L7 y# c- B$ r
- 2 J0 ^* z- W. }/ G5 J/ g9 l
- return (int) (res % 1000000007L);; u- r v# x6 R h( v8 Z4 E& d
- }
- T& r8 l* g! [# F - }
复制代码
0 P$ ` j5 @2 l# H0 YNo.4 有向图中最大颜色值
& p$ F l% J0 m- o+ g4 j- N. l
7 T# [$ w" L; H9 Q4 e; a解题思路4 ]) G# d" ?$ a, ?2 W
* Y. z( N" Q; `' C1 }; |
先判断图中是否有环,有环直接返回 -1.
$ v' N' W7 F' J4 f
& `8 z! v6 s1 r无环的话则使用动态规划求解。6 K W4 {6 J! m. G; ^5 f
+ U# b) ^7 {" w0 R, o代码展示8 q3 F4 o' u+ E% G
( I: b& Y- m, o8 t
- class Solution {
- ]/ u8 v, v8 r$ c- a - public int largestPathValue(String colors, int[][] edges) {" |) `. X/ r, x
- // 建图
3 O1 }+ C% V' n1 w; F' U - int n = colors.length();) Y1 v% e' W5 f& m# u
- Node[] nodes = new Node[n];
! B0 w5 E, `' s. J( a: I- u( g; T7 Z - for (int i = 0; i < n; i++) {5 L1 @5 t- v: Q" c, v3 H
- nodes = new Node();! N' [. T0 s" @) c; C
- }0 B/ d4 |5 M+ ?% |. n, V6 D
- for (int[] e : edges) {& m# G; H# e' a9 n
- nodes[e[0]].nei.add(nodes[e[1]]);+ T" ?' M) a* r/ ?' w) r
- }
2 l) I% ]+ J. b7 h - // 判环
( c( ]' R) A% _! L" f5 g/ O0 ^ - for (Node node : nodes) {
* Q2 \: `# b" Y/ u1 s# W - if (findCircle(node)) {; g* u `/ s$ U) n
- return -1;& b2 K% M. I6 f
- }
- J9 v: t7 C6 q6 }* o - }
( K9 I/ |3 Q5 D - // 动态规划
9 h. S2 l' c0 b' g$ J - int best = 0;) q6 V( y) b* u) E. Z5 E
- for (int i = 'a'; i <= 'z'; i++) {
+ l" y/ P7 @, R) h - for (int j = 0; j < n; j++) { Y1 _1 L5 `. e2 D+ J2 q' ^% g
- nodes[j].dp = -1;
3 c$ E2 Q7 t; V# k/ m; o8 D' e - nodes[j].val = colors.charAt(j) == i ? 1 : 0;
t$ h5 e4 ~% w' o2 O - }- E/ |9 Y: m1 ^9 n2 n
- for (int j = 0; j < n; j++) {
! B( {$ W9 Q! Z0 E+ p1 W/ C - best = Math.max(best, dp(nodes[j]));/ }% g. N' W" J& z
- }+ U# m) N' ^. V
- }: w; M# N2 w' k4 F+ {6 V( u
- return best;
1 z& o: [/ {3 n0 S- S8 b/ Z f X - }
) Z% R+ V7 D8 f7 r( p - + J" _% c+ G# e: M" F% b8 e O
- public int dp(Node cur) {
% g$ r1 J( Y: g2 E1 l - if (cur.dp == -1) { z7 z7 ^' ?5 C5 v ?9 z8 e
- cur.dp = 0;3 u; d6 l3 t2 D3 O" k0 r9 W
- for (Node node : cur.nei) {2 ?+ k/ g0 l n J1 u* r3 A: h
- cur.dp = Math.max(cur.dp, dp(node));, `) V- e( ?" l0 Q( w" S: D. _, W/ K
- }" z6 O: Z* r* T* z/ {2 k
- cur.dp += cur.val;
% i& C9 u. M; O3 d& G: a - }2 O5 p" R2 ~+ k: h1 q0 O1 _: w/ O
- return cur.dp;
+ F2 n* o# S3 Y8 U0 X# N% U - }
+ w- |: C! z; u$ V
/ D" Y# Z- G/ t1 d! Q) u( L- // 精简版的 Tarjan 算法:2 R1 w! x1 p' G& t' ]! M+ r
- // 仅用作判环,而无需求出强连通分量- V- F# ]$ o# q+ V, D' @, U
- // 所以并不需要真正使用栈,只需要一个标志位即可" x. Z4 b) Y4 u
- boolean findCircle(Node cur) {* j. i' u: D: w, O
- if (cur.vis) {6 f9 j4 R! E8 g4 c" a7 ?$ v" a
- return cur.stk;
]0 b0 M( R- M+ A - }
. j* \5 [2 y4 G2 Y+ O - cur.vis = cur.stk = true;. p$ a5 \0 l6 m
- for (Node node : cur.nei) {: h" w% l: C: X/ o; k, `, N
- if (findCircle(node)) {
) U& T& r% `0 Q! r ~+ I0 q - return true;
8 b# Z3 V* _, S1 S, s% P - }
& _8 x) R) Y9 V+ ?4 ?5 J - }
0 c' Q- i! |' C! H1 C) H4 m* N) ? - cur.stk = false;5 `1 n0 Z3 m) c# }5 E- B7 Z1 f& A
- return false;
& B/ d' j( F+ k6 C - }3 x7 F* w: W d" j) L+ T
- }
! w: @2 K- ?! O& @- j1 `$ p
) [# z3 f) A1 l, t6 f8 u- class Node {
t2 f$ r+ c0 A" K: ^2 J - int val, dp;
! h& D ?9 w% |5 \9 J - boolean vis, stk;4 Q, O9 E" O# U- J2 \
- List<Node> nei;2 h! L9 L' n: x. d4 Y3 U
- ]4 C3 U6 |% y7 l
- Node() {
) k0 t I# u. E! ^4 \1 J% U - dp = -1;
+ h: N3 n5 ~; X# W6 b8 |0 u& m) K - nei = new ArrayList<>();9 w; Y7 }& D6 k" N0 v
- }
) H" J4 c4 q' b$ U' s9 w3 Z - }
复制代码 . K" r# a* V/ g& h2 |. H
" @7 D" Q7 x+ x2 z7 r- b |