找回密码
 注册账号
置顶:如何加入2024届新生微信群

[吹水聊天] LeetCode Weekly Contest 240解题报告

上岸算法 回复:0 | 查看:3375 | 发表于 2021-5-10 05:21:00 |阅读模式 |复制链接

UWCSSA提醒您:

警惕网络诈骗与盗号,不要在他人发送的网站中输入密码,换汇或付款时请小心诈骗。

为了避免个人信息泄漏,建议在帖子中使用不常用的邮箱,或使用私信发送联系方式(点击对方的头像,然后“发送消息”)。

帖子通过审核只代表内容不违规,CSSA 不会验证内容的真实性。请谨防诈骗。

No.1 人口最多的年份& r# h& A  y9 [) b9 Q
2 D* t* C+ B5 Z$ p8 r
解题思路
, ^, u+ H4 i$ ~; i5 a6 o$ M& i: L( R' }8 w! z% \7 s) B6 c$ [
数据范围比较小,直接枚举统计即可。. u+ i! `  t' I0 H' g6 H: w
: d. j6 B, S# M: X2 Y4 U
代码展示
9 c$ q$ y) R4 d! f5 B
  1. 6 O6 m: e* k* ]) q2 W! y
  2. class Solution {
      w/ T+ X: o* h4 a  ~: f* h
  3.     public int maximumPopulation(int[][] logs) {
    * w* q' ?8 F( \8 ~
  4.         int[] population = new int[2051];
    * d, A: a* E# w4 ^
  5.         for (var log : logs) {
    ) X8 w& ~6 s3 U/ k% f* |
  6.             for (int i = log[0]; i < log[1]; i++) {% o8 z- G; x9 c' m( D, Z
  7.                 population++;
    / B- w( E' M1 |+ O4 C$ Z, G
  8.             }; I; w: V, j9 K  n8 l
  9.         }. ?8 `  E9 Q+ ~, H
  10.         int res = 1950;
    3 L) Q  ]- G$ G/ H" w7 e/ M  p
  11.         for (int i = 1951; i <= 2050; i++) {
    / J/ |& u' I5 P& \0 }3 f' I- a* W
  12.             if (population > population[res]) {. X; I* w. O# i# U% E6 f! n
  13.                 res = i;
    7 a' J$ A  l9 h" `
  14.             }; @- J; `7 N0 d2 q; _+ y4 _
  15.         }# ~- J, M1 h( E
  16.         return res;6 a5 i$ J8 O% j! z( x+ o: m* O- }! j
  17.     }
    9 P9 r* l' V" y; [6 }. s
  18. }
复制代码
; @% ?, g8 r! w

. }. v; i" J& b) ^  X; fNo.2下标对中的最大距离
, m0 b# G; [# @7 ?9 F
4 `% E0 [7 b; }解题思路

& A- ]9 f0 S: P* D  ?1 d1 W& ?8 ^4 ~% w
输入的两个数组都是单调的,可以使用双指针。5 F5 Z! O5 ^4 t

% q: Y/ O* t6 `) ~: n3 Q( U2 c3 v代码展示
3 z; M& _: W* Z8 a6 Q
* M- d1 G' p3 o+ |
  1. class Solution {7 n; t: G0 h- x2 T! E
  2.     public int maxDistance(int[] nums1, int[] nums2) {
    % j6 \1 J. I+ C! H: [2 F, w
  3.         int n = nums1.length, m = nums2.length;
    . @2 b$ ]9 p2 G# ^  R
  4.         int res = 0;
    " n" T- R! T3 m$ A6 i0 ?1 h
  5.         for (int i = 0, j = -1; i < n; i++) {5 W& `# j9 O) b" A# {4 [
  6.             while (j + 1 < m && nums1 <= nums2[j + 1]) {
    & m8 P# A$ M6 x' v0 o4 m
  7.                 j++;
    7 a: x& r- d" N; E
  8.             }6 Y$ M0 }* I! H! l) V1 O5 q
  9.             res = Math.max(res, j - i);
    6 p% d' `. i7 y3 {7 ], I9 @$ g
  10.         }' |5 g$ {% S( W
  11.         return res;
    ( |9 ?& g% h0 [. s
  12.     }* N4 C  f( @# ]0 `
  13. }
复制代码
! r4 L% {( @8 U+ W/ d7 X( Q
No.3 子数组最小乘积的最大值6 o4 b7 B8 k; k* x

% R; e& s( T" r0 r解题思路
0 M( \/ R1 G! }" c9 \" j1 O' v2 x2 b( c6 n1 O, P) z5 w
单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。5 `" s2 b) V6 [* W0 X7 B9 i! j

7 M( t* v5 E0 o当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。
! G  z( {( I# F2 p1 [
& ?  w- j- a- b: V代码展示

  Q: q9 E! u/ U  B! j1 U4 f) }0 W* ~4 b: R9 a. v; Z
  1. class Solution {
    : H: p( Y1 @, i, E3 i
  2.     public int maxSumMinProduct(int[] nums) {
    : v9 S8 u& @+ f% }: p& c
  3.         int n = nums.length;
    ! H4 x+ }7 b( _$ w
  4.         long[] preSum = new long[n + 1];
    0 K8 z/ j5 E  d: H, O6 P* Y  H8 e
  5.         for (int i = 1; i <= n; ++i) {4 Z: x4 ^' J3 H  P6 B
  6.             preSum = preSum[i - 1] + nums[i - 1];
    ! @0 a2 {4 ?/ k, n6 B6 `! H3 W" R& p
  7.         }( x2 I$ r4 Z) U4 j% I" M# ?
  8. / }! g; K) ?: F2 m
  9.         int[] l = new int[n];. A5 r; K8 U: I
  10.         int[] r = new int[n];
    * F1 j  m2 ^% V) k7 z0 Y
  11.         Arrays.fill(r, n - 1);
    5 q8 u) ^" o& d' A) q6 c1 p4 U

  12. ( B1 q/ T3 N1 B% `
  13.         LinkedList<Integer> stack = new LinkedList<>();
    / {7 h/ @! k3 a/ D3 F
  14.         for (int i = 0; i < n; i++) {; v' P, T; f. K" [5 s- C5 o
  15.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
    ; [* Y5 i6 p4 q1 Q' y3 |
  16.                 r[stack.pollFirst()] = i - 1;4 G6 Q) V/ C9 E
  17.             }( K9 i, L# l, B0 Q0 F/ K# q
  18.             stack.addFirst(i);
    9 p" s% g: x" Z6 Q  X6 g% ]
  19.         }/ H4 g3 z$ _# ^' y$ ?
  20.         stack = new LinkedList<>();4 M; v: j/ ~2 L; ?
  21.         for (int i = n - 1; i >= 0; i--) {# W% Y; J* O0 G3 k& f- p# H
  22.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {/ ^( s  P; e' t7 T3 G1 t6 k
  23.                 l[stack.pollFirst()] = i + 1;7 b1 D* ~- G3 w, r
  24.             }# B! u' d  K( Z9 W3 Y- A# X/ V
  25.             stack.addFirst(i);: [& L& m; f9 I3 Y# T
  26.         }
    3 x  f' n" \6 |

  27. ( a2 E. t+ D' D3 o0 h
  28.         long res = 0;4 K* y. h; X" P3 p5 c1 D& j7 L
  29.         for (int i = 0; i < n; i++) {* c+ ]: r" z! Y% N! |$ o
  30.             res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
    # T9 S- ^$ K/ ]& p6 m3 b& O; w1 \) B
  31.         }
    9 r+ @# V: m9 _5 e
  32. * K4 a" b( H( s; b
  33.         return (int) (res % 1000000007L);7 W- N, q2 D! Y( P/ m8 O( S
  34.     }
    5 o" x. c& D5 Y' E8 m8 {/ b1 q$ j
  35. }
复制代码
- O. Q! ^2 o' l- h. [' c5 I/ X. s
No.4 有向图中最大颜色值
9 i$ d  S* a( ?2 }3 ?. ?; v* J/ s2 G
; _4 x# x8 {5 S) k' y2 k8 @解题思路
  ?* e# C" _* D* P$ k$ u9 H# V- A: m3 z2 A" f
先判断图中是否有环,有环直接返回 -1.
8 G2 p, Y$ M$ F! e( ?2 \3 g: s2 a: Y& p! i/ d# k' X" x2 F+ X/ B
无环的话则使用动态规划求解。
$ x: t% Y2 _' M2 M+ f; v$ z
0 [7 ]8 E# B: L0 R/ b4 p代码展示4 n9 f# m. I7 M# `; S* [

! j- L7 Z! x5 X
  1. class Solution {( R9 P6 C# a' \$ |* K5 |
  2.     public int largestPathValue(String colors, int[][] edges) {
    % @! e3 s0 w: Q; e
  3.         // 建图5 V2 q% v( A( I. W
  4.         int n = colors.length();
    + O) K) \( h# R9 p* u+ l2 T  k0 X4 l
  5.         Node[] nodes = new Node[n];& I0 C+ a/ _9 K( U# i
  6.         for (int i = 0; i < n; i++) {, ~$ O$ F- d0 x2 w5 b
  7.             nodes = new Node();3 L" ]* j0 l0 S. A5 I( c
  8.         }
    " u' n/ g. ^- g" Y/ R. q, H
  9.         for (int[] e : edges) {
    8 C1 l8 K) z% g, w4 }* p
  10.             nodes[e[0]].nei.add(nodes[e[1]]);: L+ M# U; ^+ |# q" a1 b
  11.         }
    0 y2 [' g& \4 D' r
  12.         // 判环/ {% \& l7 {. S% L5 \0 s
  13.         for (Node node : nodes) {
    ' e# ?4 A6 V5 ]7 I8 A6 k
  14.             if (findCircle(node)) {
    & n6 Z- A, p/ D* ^7 x/ N8 P
  15.                 return -1;
    ! y9 H8 d. `9 Q. N2 a
  16.             }0 J1 \! a6 c3 |, D" e) @
  17.         }
    6 @0 a& u7 N1 L" Q& c) z5 c, D- O$ K
  18.         // 动态规划2 I. L9 d# g% y' w/ {) l# s
  19.         int best = 0;
    " b; k% G8 h7 h
  20.         for (int i = 'a'; i <= 'z'; i++) {
    * q2 X6 {4 Y" c6 d
  21.             for (int j = 0; j < n; j++) {# {+ B4 e, |6 H& ]2 s9 G$ ^& W
  22.                 nodes[j].dp = -1;
    ) l& E6 i' P  ~; i# F; e( R
  23.                 nodes[j].val = colors.charAt(j) == i ? 1 : 0;
    5 ]! Z2 @0 {/ n' v: G4 y- D
  24.             }9 ?8 |- B7 k! H, @* @9 [0 [
  25.             for (int j = 0; j < n; j++) {. t. ^; X4 H$ W! b4 W; U
  26.                 best = Math.max(best, dp(nodes[j]));  w- ]# k* i5 X  m$ j+ Q
  27.             }4 K/ ?; e% A' Q  Q( D2 d+ I
  28.         }; W. B4 @+ h+ }0 z  z; i2 Y
  29.         return best;
    8 f( _1 @5 m$ R, e5 E# }
  30.     }
      M1 b/ N- a* p- K; h( @0 K

  31. + s  H  V2 _, k% X7 B4 W* k
  32.     public int dp(Node cur) {2 G2 h. \- |4 n. ~4 F( \
  33.         if (cur.dp == -1) {
    , m1 o& D- ?+ O8 K
  34.             cur.dp = 0;
    * h1 e+ Z" H9 O3 }$ v& f& u
  35.             for (Node node : cur.nei) {  `, D5 m; D# y4 d# `# @; ^
  36.                 cur.dp = Math.max(cur.dp, dp(node));
    $ X% F+ [2 X. }" l/ M# r
  37.             }9 Z4 i( F' X* ?5 M7 S) i1 }# v! V  w5 _
  38.             cur.dp += cur.val;
    5 v$ d5 L7 o7 Z/ J8 s) |9 P& q; G3 I
  39.         }
    7 z) _6 {( E1 U9 @
  40.         return cur.dp;# H) B' {* H4 Q' l. Z+ |9 h' `' P& D
  41.     }, Y6 X0 c  ~/ r- }% H
  42. , i, O% {6 Z: P$ {1 `+ C
  43.     // 精简版的 Tarjan 算法:
    ; u7 ^$ s/ m* n$ {! C- l
  44.     // 仅用作判环,而无需求出强连通分量3 s1 [) }) p% M7 P/ a# Z
  45.     // 所以并不需要真正使用栈,只需要一个标志位即可
    . J# o# x2 w2 i
  46.     boolean findCircle(Node cur) {
    . c- g& B  E& g8 v+ B8 V% s
  47.         if (cur.vis) {
    9 ?8 y! Q7 r% T! e1 }
  48.             return cur.stk;
    2 G- e( ~9 m  ^: j" q
  49.         }
    & E& L% L* |, z- w. Z# t
  50.         cur.vis = cur.stk = true;
      ]3 H& O% @1 k0 U5 p3 K5 `# O, @
  51.         for (Node node : cur.nei) {. @( I# `2 f# I( w& N
  52.             if (findCircle(node)) {
    : o. b# E: v% M0 P: \# D! t
  53.                 return true;
    " Y5 n8 ^" W$ a8 G1 W5 @
  54.             }5 \4 i$ W5 F+ k. m+ h" r2 D
  55.         }; |& |- ^$ [  ?8 W) D( E
  56.         cur.stk = false;+ M, U5 w; E% o' e+ I, t
  57.         return false;
    - }9 X  }+ @9 }% L
  58.     }
    5 D: a5 C& j1 A" ~
  59. }0 X9 ^- P& M: A8 Q. }6 n8 H, _

  60. 4 y. Z* R6 f/ d& N
  61. class Node {! d4 b- f6 [. e' _' d6 u
  62.     int val, dp;/ I% s5 i% I: p8 d$ _* J& G( L
  63.     boolean vis, stk;
    4 J9 |/ o* V& k0 j
  64.     List<Node> nei;
    7 y! j# ~1 s, w6 [3 }3 F1 _1 Z% e
  65. 0 u; E2 ~4 S3 @
  66.     Node() {7 Y& Y$ {$ v. f; x7 l5 S
  67.         dp = -1;, ~( Y5 o/ {9 f  a) d, h; h$ f
  68.         nei = new ArrayList<>();6 Y- C/ f; y' b/ C
  69.     }
    7 {: b& U6 a( T- l! a) z
  70. }
复制代码
- Z6 _( Q/ L" S, j

7 [# I/ |5 N# V$ H+ i* d" W

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

登录 发布 快速回复 返回顶部 返回列表