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

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

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

UWCSSA提醒您:

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

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

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

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
  1. 4 L' C' [+ x, {1 F8 c
  2. class Solution {
    ( R- t* h" ]' r- h, i$ G$ @$ \
  3.     public int maximumPopulation(int[][] logs) {
    8 x' N- k' u5 X3 ?+ a
  4.         int[] population = new int[2051];! ?: ]2 Y' r, r. x  _+ C9 Y
  5.         for (var log : logs) {
    2 N* g  ], q1 y2 O% l$ U
  6.             for (int i = log[0]; i < log[1]; i++) {
    0 n7 ~' f7 y) ]2 }" X
  7.                 population++;
    ! s  l6 P. D) f! s
  8.             }7 x+ M5 j; }' }/ f
  9.         }# g0 E  z7 Z( E1 r
  10.         int res = 1950;
    " f9 T, t) s! H/ P! [, F0 j
  11.         for (int i = 1951; i <= 2050; i++) {% p+ C: t) H7 Q6 ?
  12.             if (population > population[res]) {
    : n3 x7 n$ m) q- }; g
  13.                 res = i;
    % m3 v: H4 o9 ]* d3 e+ k
  14.             }9 Z8 F9 z( l$ H8 J% c- U$ z
  15.         }
    # ]% c( J, f# |5 V
  16.         return res;
    / Y/ P$ V$ [) {' ~  u# l
  17.     }$ s- l6 O% p' j; s) B
  18. }
复制代码
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! [
  1. class Solution {
    ! V$ |/ H9 K+ n0 p
  2.     public int maxDistance(int[] nums1, int[] nums2) {
    * n4 K4 U6 F, L
  3.         int n = nums1.length, m = nums2.length;
    0 X6 W& @! G5 k% {/ \' k. o6 g' m
  4.         int res = 0;
    % b9 G3 V4 y, K4 j* |
  5.         for (int i = 0, j = -1; i < n; i++) {  I% D7 U: j: t  K
  6.             while (j + 1 < m && nums1 <= nums2[j + 1]) {  [$ `$ P6 B* ], F
  7.                 j++;
    ' g# w8 T- I- y! A- C7 N
  8.             }
    " L7 x% L& k( H  y' d8 M8 k
  9.             res = Math.max(res, j - i);
    1 p! S6 N2 N$ ]( R  C' j* G
  10.         }
    : O8 ~/ j) I2 a5 E
  11.         return res;; w. ^' v; ?5 V7 ^: J0 {* `8 z
  12.     }
    & O0 M. C7 L0 z% n: U0 L7 {
  13. }
复制代码
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" ]
  1. class Solution {
    + e6 V" Z6 H+ _. H& h
  2.     public int maxSumMinProduct(int[] nums) {9 U7 G; g9 E8 |- r) _9 g* r
  3.         int n = nums.length;# G: E& v( I5 [# X) w( q
  4.         long[] preSum = new long[n + 1];/ f" v! C& v/ O( x1 l" K# @; }/ r
  5.         for (int i = 1; i <= n; ++i) {
    5 J5 G! b5 W- ?5 a  }
  6.             preSum = preSum[i - 1] + nums[i - 1];$ K  Q' Z5 }0 X+ o0 ?& ?/ ~
  7.         }
    / g. u; w( {  ^: e0 a7 e1 S7 w

  8.   y2 K8 w2 t- D7 W( d9 ^# R
  9.         int[] l = new int[n];" b! [' p$ w8 i5 b1 L4 h4 q
  10.         int[] r = new int[n];
    4 D" X( _) ?( o+ h2 h: T9 g
  11.         Arrays.fill(r, n - 1);  v4 c0 x3 o1 P
  12. 0 u! ]; i' h6 {( `9 O% |: X
  13.         LinkedList<Integer> stack = new LinkedList<>();
    1 l! \8 J  Z' q+ k: e/ H1 q
  14.         for (int i = 0; i < n; i++) {
    * R8 w+ S  {# f9 Y
  15.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {1 w. P" P, P8 k7 g
  16.                 r[stack.pollFirst()] = i - 1;4 W) {  c1 O; U0 n- c
  17.             }
    " N" I! E$ j5 N3 j& q2 f" }* R; W
  18.             stack.addFirst(i);
    3 O4 t5 G- l& l6 }$ x5 j, F
  19.         }
    7 V6 i5 a3 I8 V; e
  20.         stack = new LinkedList<>();4 p! C( |6 }8 I# ]6 A
  21.         for (int i = n - 1; i >= 0; i--) {2 Z2 R, G2 l* ~) d( g/ B- \
  22.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {  W0 A) S& ^6 b5 Q* T3 W& u
  23.                 l[stack.pollFirst()] = i + 1;( I7 X. M4 L7 v/ d* u. t  f+ g
  24.             }& {) o, g9 j; q+ k" }
  25.             stack.addFirst(i);; U1 S# N' G2 _! T& S
  26.         }. X5 ^0 V. ]1 F4 q
  27. ) ^  r* ]1 A' h; w: t. v
  28.         long res = 0;
    6 j3 Z  C: P# b, x$ L( k
  29.         for (int i = 0; i < n; i++) {
    / W( K6 R* `4 r( H  e) q
  30.             res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);( I+ R+ O' L4 K* c
  31.         }. R0 ?8 U; p3 P8 ^

  32. 6 ^) z8 S. w5 v: c5 k
  33.         return (int) (res % 1000000007L);% g6 r: A5 y8 t
  34.     }
    # {- J  P+ H" O
  35. }
复制代码
' 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
  1. class Solution {5 e- c7 e9 c# {" L+ `/ s
  2.     public int largestPathValue(String colors, int[][] edges) {" x" t, z+ J5 L3 I; r& ~
  3.         // 建图6 C: t* ~% N' h. t6 u! ]9 G
  4.         int n = colors.length();1 v( X$ y2 g; m
  5.         Node[] nodes = new Node[n];
    7 |# Y  T/ Q1 A
  6.         for (int i = 0; i < n; i++) {* V- V7 E! f6 X# q
  7.             nodes = new Node();- T( _3 }' N* Z# n. V/ Q' c
  8.         }6 D& X2 ~" b9 j9 ?
  9.         for (int[] e : edges) {: @2 N$ C* W+ Y2 ]
  10.             nodes[e[0]].nei.add(nodes[e[1]]);
    , R& a" l( A+ L. l) M4 f1 D3 @8 r
  11.         }
    7 A% e" U0 c2 q4 U# {
  12.         // 判环
    : `% |% n: l: o5 M# u" ?5 d
  13.         for (Node node : nodes) {2 i% a. B1 O8 X7 O" E6 w, K
  14.             if (findCircle(node)) {
    , i! e" S* j( J' ^$ ?0 b
  15.                 return -1;
    " j6 Y5 H" a9 ]/ x1 c
  16.             }
    ! V8 ]: f6 ~( V( V% C* a( R
  17.         }
    0 b( k; P% J( T0 T9 ~0 z
  18.         // 动态规划
    * U+ R5 h# Q5 z' R# @3 Q, p
  19.         int best = 0;6 l/ c: A( v/ P* P
  20.         for (int i = 'a'; i <= 'z'; i++) {8 p0 {) @! c0 \. N' s. G  i
  21.             for (int j = 0; j < n; j++) {6 O6 m+ q" @% g6 N
  22.                 nodes[j].dp = -1;0 K: q; {( M- x. a. ^
  23.                 nodes[j].val = colors.charAt(j) == i ? 1 : 0;+ ~+ _$ |% S5 g% w, t! b. `: g
  24.             }+ ^9 k$ q: g- d4 p: g1 Y
  25.             for (int j = 0; j < n; j++) {6 |, _; ]. y3 R- J$ E/ p' ^1 U& r$ f
  26.                 best = Math.max(best, dp(nodes[j]));, b# ^( I1 R- u$ b
  27.             }6 E2 d$ p0 c# g" H6 r
  28.         }/ g# ?; J8 Y; e0 i7 ?! F/ J( d
  29.         return best;
    ) h. J" h5 f: P' y6 |  F6 s
  30.     }
    * t3 P+ R( t( T: T3 A9 h. B& B

  31. ' ]6 k0 n/ E, G1 W5 _$ W) |
  32.     public int dp(Node cur) {" \4 q# h3 F$ H$ d' _
  33.         if (cur.dp == -1) {
    ' i. y# y5 b3 _* G
  34.             cur.dp = 0;
    8 q( m' B+ E" N& C6 r2 o' M
  35.             for (Node node : cur.nei) {
    ( @* o7 M# m! H) N' @
  36.                 cur.dp = Math.max(cur.dp, dp(node));
      j' B1 M+ O' c5 a4 [5 R7 _& F, e
  37.             }
    / _7 J& J9 f. k4 e) p
  38.             cur.dp += cur.val;# x# k" A, {, O
  39.         }& M. T9 m# W$ a
  40.         return cur.dp;/ @7 n' q0 Q( Y" q5 o+ X' o
  41.     }
    , A  i3 ^4 R' k1 X" L# h' E

  42. 3 z3 U' q0 Z, J
  43.     // 精简版的 Tarjan 算法:. t, g# R7 P4 i- Z0 x
  44.     // 仅用作判环,而无需求出强连通分量
    , G" A, P/ }9 h' I8 `* n
  45.     // 所以并不需要真正使用栈,只需要一个标志位即可7 B6 |+ d+ K, S1 |, U+ ~! z
  46.     boolean findCircle(Node cur) {
    . x% c+ G5 L1 \# P
  47.         if (cur.vis) {
    3 h+ ~! [9 e) ?# l  }' a3 R  g
  48.             return cur.stk;
    7 f3 r; N+ A0 S+ c: n
  49.         }7 R" B$ V2 ]+ N+ @0 b& Q$ T
  50.         cur.vis = cur.stk = true;
    ( P4 C0 f' M7 R# {7 D. M& N
  51.         for (Node node : cur.nei) {# v/ U& n/ x* }: U
  52.             if (findCircle(node)) {
    8 u) x4 w2 Z( K3 a- V1 m. }
  53.                 return true;
      h4 r6 Y) @! K; x5 f2 h8 J
  54.             }
    6 |; J7 B( j1 O1 D; @- O( O% v
  55.         }
    - Z; K8 C! f- V, d& M) c9 }; \4 T
  56.         cur.stk = false;
    : A0 e; V8 `( S# p& J  A3 a/ \
  57.         return false;
    " o; U) P  @0 G. {7 ^$ o
  58.     }; t$ h; r9 v" [# r% F
  59. }6 E0 O) D2 E# Y) Y7 B

  60. " `* k* {; K9 B. E
  61. class Node {8 w- k2 z0 }9 a% d/ f% u+ A
  62.     int val, dp;/ R1 w+ B8 z& u* a3 G! C, \3 ^  @
  63.     boolean vis, stk;
    - ^$ Q+ X" k1 a% |& V7 c
  64.     List<Node> nei;
    $ O1 G. W, l2 L# u: @3 J
  65. ) r1 m& C& @& l0 |9 A5 [
  66.     Node() {1 [9 b! T6 s" e: o. u. \) v
  67.         dp = -1;
    " V6 l7 e& H9 w& k# N6 ~
  68.         nei = new ArrayList<>();' D8 s: p% l+ M' n" w
  69.     }3 S& E, ~1 A8 M! z2 H- Y& i# g& D
  70. }
复制代码

2 M% D$ b5 f3 \) }; K
8 a. I: ^1 r5 {5 p( t

本帖子中包含更多资源

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

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

本版积分规则

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