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

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

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

UWCSSA提醒您:

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

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

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

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

  1. ' D) ]8 Z0 M7 M* f$ \$ ^3 L
  2. class Solution {7 j0 z. F" ], Q( i5 _! `
  3.     public int maximumPopulation(int[][] logs) {
    ; \) V; Y# T, G: r
  4.         int[] population = new int[2051];
    ; O9 F$ D, B/ D( r# U5 N  u4 N
  5.         for (var log : logs) {
    ; j7 C) j+ K9 G2 {! r
  6.             for (int i = log[0]; i < log[1]; i++) {
    # r/ Y0 q; I, O+ V" a/ L  Q- e# q* T
  7.                 population++;
    " u+ o$ f0 |/ ^$ E5 `; a
  8.             }% M' r: S. g2 k6 O" j& ^( q
  9.         }' G3 k: K$ `( g! u9 [
  10.         int res = 1950;
    3 M; I! r- I" J: A: |3 {
  11.         for (int i = 1951; i <= 2050; i++) {3 m8 m7 f6 ]: U, B% S+ ?
  12.             if (population > population[res]) {; k  i9 W/ _$ g4 Z0 q% @5 ^
  13.                 res = i;! h2 K3 K5 S+ q2 F% M5 \5 ~
  14.             }/ Z, V# ?9 V. |1 D4 ?' u
  15.         }$ d, N: ^: J+ [4 e  y0 p
  16.         return res;+ P3 r8 m3 V8 L$ E# x5 y( v
  17.     }- i# b3 Y8 R* _; m, w* u! U) \
  18. }
复制代码

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
  1. class Solution {9 t7 Q2 n. \: J7 G+ U
  2.     public int maxDistance(int[] nums1, int[] nums2) {6 L) m; ~3 r2 |
  3.         int n = nums1.length, m = nums2.length;; X& p  `. Z9 `, i8 i/ ?. O
  4.         int res = 0;
    ; ]8 H' q/ J' K& _
  5.         for (int i = 0, j = -1; i < n; i++) {+ v9 m" C! I8 p: U2 ^6 ^
  6.             while (j + 1 < m && nums1 <= nums2[j + 1]) {
    - h: p& g( c  t0 g# j% Z, w2 o
  7.                 j++;
    ' }3 c8 Y) u& T  n
  8.             }
    9 J  {- G, d$ M) O+ T
  9.             res = Math.max(res, j - i);
    : m$ r. i4 d" R5 X# y
  10.         }
    $ M2 P2 Y- ~& G
  11.         return res;
    1 X" @0 ~0 \8 F7 ^+ _
  12.     }! B0 }* F; M2 c& g* |( I
  13. }
复制代码

+ 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
  1. class Solution {- r2 X/ t4 z: l- {" F
  2.     public int maxSumMinProduct(int[] nums) {# f' [' S/ P- U  u& K% m
  3.         int n = nums.length;+ d1 ], k$ m' b
  4.         long[] preSum = new long[n + 1];
    - R/ e6 q0 j" h
  5.         for (int i = 1; i <= n; ++i) {
    , O$ m( ^6 u% y% d4 H- f3 @% ?
  6.             preSum = preSum[i - 1] + nums[i - 1];
    5 L: H: w7 o0 f' ]: O+ a. _
  7.         }
    1 z, t; a# l: K9 a6 p
  8. * J7 X+ |' J. J" Z0 ^9 G2 T
  9.         int[] l = new int[n];
    ) f% ]& \0 f! |. H" T( m- O) s
  10.         int[] r = new int[n];
      n) _. _/ B! r
  11.         Arrays.fill(r, n - 1);; ^4 @% r# O" z% p7 C6 L, m
  12. 1 P) y2 F( D: Y
  13.         LinkedList<Integer> stack = new LinkedList<>();. I; V& t/ E6 U4 O- z# l
  14.         for (int i = 0; i < n; i++) {" M4 U' Q- r  b& D8 f" R
  15.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
    + V5 D1 P: u& E. ~
  16.                 r[stack.pollFirst()] = i - 1;% z6 `3 k& V& o, |- {1 ~: s
  17.             }- y- u$ J9 r3 e6 F
  18.             stack.addFirst(i);  C# g9 b8 A$ Y  K/ Y9 N2 F! R$ Y
  19.         }8 q9 s( u& f) H$ q/ t9 N& J6 M
  20.         stack = new LinkedList<>();  |2 D7 Q% }0 b8 F0 D
  21.         for (int i = n - 1; i >= 0; i--) {1 M0 r- A3 C3 Y# @
  22.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
    . Y  c7 x! N8 H
  23.                 l[stack.pollFirst()] = i + 1;' U4 s8 u8 N" @1 H5 F
  24.             }/ ], ?8 S$ V( I" Q
  25.             stack.addFirst(i);
    5 U) j. j' w. }) c
  26.         }
    : g; a: R* [  ]1 K( F
  27.   {7 c1 R& g9 C+ U% C" e
  28.         long res = 0;6 d# `1 b4 u8 e! p0 k% U5 _
  29.         for (int i = 0; i < n; i++) {
    % {, j! `8 b3 N5 }3 [
  30.             res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
    ! o9 [1 `6 n: N2 |3 w9 n, R
  31.         }" m' Q3 R( J9 E$ o; b# g
  32. % e6 }6 D: m+ }& i0 M) X
  33.         return (int) (res % 1000000007L);
      l0 X% I! L  k# n& x% v2 v) O+ U
  34.     }
    ' t$ a1 ~2 E) D6 s9 p& I
  35. }
复制代码

$ @$ 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
  1. class Solution {3 y' K; R: ~0 F* V, p# M
  2.     public int largestPathValue(String colors, int[][] edges) {
    " w% c& p; f& ~# a# y) N/ i
  3.         // 建图! j0 v, E* ?8 I3 y, V* h# m
  4.         int n = colors.length();
    4 W5 ~" p, W  P$ T( @' y
  5.         Node[] nodes = new Node[n];
    2 H, Y: S" }/ U5 l3 B/ U
  6.         for (int i = 0; i < n; i++) {4 [* F) U$ m4 ?) a( F
  7.             nodes = new Node();: P/ [. ^) X: e0 Q5 B# Q
  8.         }$ o" J$ H; }/ x9 l* B5 t
  9.         for (int[] e : edges) {
    7 ?8 H; G1 \! y0 k
  10.             nodes[e[0]].nei.add(nodes[e[1]]);: @! |! l* w) Y# H7 Y1 m7 s2 d
  11.         }0 a0 {1 j$ c$ P, z7 c) ~2 l
  12.         // 判环
    : w" c% y' h# \" q" f5 m) O, X0 \
  13.         for (Node node : nodes) {: k; `) _/ F  N+ ?1 G8 r% V8 A
  14.             if (findCircle(node)) {# U+ V% P- e. E
  15.                 return -1;' B* _0 F* x3 j/ P
  16.             }
    8 p) h) F/ W! M+ b
  17.         }
    . D# a) C3 F2 s+ r1 C4 J
  18.         // 动态规划* z" b/ v' w. t) N$ |" u
  19.         int best = 0;
    8 i* ]: G* J& B# @
  20.         for (int i = 'a'; i <= 'z'; i++) {
      a! r- N5 t, j4 U- i7 [
  21.             for (int j = 0; j < n; j++) {8 M$ r3 i4 O2 `8 X
  22.                 nodes[j].dp = -1;4 p3 _9 T- @% V
  23.                 nodes[j].val = colors.charAt(j) == i ? 1 : 0;
    + Y! ^. l# K5 Q9 ^, i3 ]2 V
  24.             }  Y7 S/ M) o9 T2 E% Y0 D
  25.             for (int j = 0; j < n; j++) {
    2 @1 }5 p# u3 ]7 M* X% j6 H
  26.                 best = Math.max(best, dp(nodes[j]));& C4 Z6 d8 ]% @/ \6 i
  27.             }
    & G0 Q% k6 ^! q" ?* |2 j
  28.         }. q. n  Y5 u! n& y3 o0 ]9 \, R
  29.         return best;
    % G7 j: p! b0 U0 W, _5 N. K
  30.     }! M3 X0 m+ s0 V# l6 d* }

  31. 7 W) t. o& w, E% U# A
  32.     public int dp(Node cur) {
      t& {5 k# ?( m8 j0 D
  33.         if (cur.dp == -1) {
    & J) B, M# |+ X' Q% q8 B* P
  34.             cur.dp = 0;
    " p$ c# n" V! X, N4 @
  35.             for (Node node : cur.nei) {3 _- V$ `# Y0 n1 p( r
  36.                 cur.dp = Math.max(cur.dp, dp(node));% N6 l! S0 @  ?3 }: P
  37.             }
    - _) ?8 ^+ ], x! }# G! O. n
  38.             cur.dp += cur.val;. Z* t5 h; s4 ?7 F
  39.         }! Y0 W6 L4 X" ~% f) L
  40.         return cur.dp;+ x4 l* H( E. E0 w
  41.     }& z- Z5 k" L* ~% |4 W

  42. % Y% |3 L0 c; a- Q& _
  43.     // 精简版的 Tarjan 算法:
    - a2 v" Y6 ]  m. t2 A$ S: [
  44.     // 仅用作判环,而无需求出强连通分量7 q: D) m# ~, L+ W
  45.     // 所以并不需要真正使用栈,只需要一个标志位即可% G# ?% c) v, O; l0 d) u
  46.     boolean findCircle(Node cur) {+ V0 G+ C- E* V' B, D' c0 {
  47.         if (cur.vis) {$ m& {; m8 M9 W5 o
  48.             return cur.stk;3 ~- }, E0 u* E. i. P0 M' |
  49.         }
    + N. b' ^  N% ~* I
  50.         cur.vis = cur.stk = true;2 m% [* Y6 f5 R
  51.         for (Node node : cur.nei) {! _6 f' S7 i% n& g
  52.             if (findCircle(node)) {( F: I8 v  V2 s" U' b& X2 F) p
  53.                 return true;, n. m( l+ S: l8 y
  54.             }
      f0 R; o# E4 t2 ]  T
  55.         }
    2 S8 ?/ C8 M+ T3 y8 [/ C
  56.         cur.stk = false;
    - I9 E; D: [' r/ W
  57.         return false;5 }0 \% e8 ^- G7 k! N
  58.     }
    5 k# y* P9 Z$ t6 ^! z
  59. }
    " U$ ?. n% c+ m* e9 M

  60. 3 ~( H, \; f+ z# @; }  m
  61. class Node {
    3 f3 l& g) N; Q+ i/ X
  62.     int val, dp;
    / B& f- t. y) [1 d6 L
  63.     boolean vis, stk;( T1 _7 ?0 O  a4 t
  64.     List<Node> nei;* b' Y8 R0 ]9 P! m$ x

  65. 9 j  Y( B$ g, Q( b2 `$ d5 e& g. |* L$ G: k
  66.     Node() {
    2 w3 [% Z8 C" w5 D& i# I
  67.         dp = -1;
    6 G- Z/ z9 Y& o4 |, L' L
  68.         nei = new ArrayList<>();* k$ m0 R. ]5 S* X2 I
  69.     }$ q5 Z7 r" b& X2 b; A
  70. }
复制代码

, t6 U# r  F7 c9 V4 R- H: V/ X0 O: ?/ {; ]4 @

本帖子中包含更多资源

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

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

本版积分规则

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