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

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

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

UWCSSA提醒您:

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

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

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

No.1 人口最多的年份
9 n0 M/ G2 l: H3 _' O! P; x% s% i4 h. ?
解题思路0 [- ]- M; H0 i4 h% E7 f8 O
6 h( ~- t/ j4 H; U0 e1 o7 G6 q
数据范围比较小,直接枚举统计即可。
% R8 j$ Z, p' m7 i0 G, A
# b) ^; S8 x. m, L7 J1 ~代码展示
* _8 V- ?! R4 e6 T0 P6 [

  1. $ B) V: O4 u5 I; Q; [
  2. class Solution {% V" s6 B6 E( x* i+ s5 o
  3.     public int maximumPopulation(int[][] logs) {; ^+ L2 H& X' |0 u
  4.         int[] population = new int[2051];( i6 C$ t: q, v# J5 y
  5.         for (var log : logs) {/ I: r* @* a8 s; \& b
  6.             for (int i = log[0]; i < log[1]; i++) {
    % s% z8 O) ~5 l( a4 [: b
  7.                 population++;
    ; G) R' }' A5 j
  8.             }  }- N5 k& I6 T# J; f) f; N
  9.         }
    . H7 B& j7 _  G; o) y! X, m- [
  10.         int res = 1950;( H. E8 @; C  ?; N, |$ \3 p: \
  11.         for (int i = 1951; i <= 2050; i++) {
    * N! E" R9 @( N
  12.             if (population > population[res]) {
    1 p5 }) H. X5 v3 L; I+ W5 D$ C0 k
  13.                 res = i;
    & Y2 b. H! |5 a5 F+ \$ ]1 x* s+ \: s
  14.             }
    " R7 h) G3 Y: m7 U" \- u
  15.         }6 R- Z  Z7 [1 U$ Y% s
  16.         return res;' E9 [8 N' p" n$ T' ?2 q" y
  17.     }% V/ D. ^7 a+ B. |
  18. }
复制代码

) ?4 ~, b. K6 r8 o
' `5 i! o9 n, }( f- b& j; ^No.2下标对中的最大距离: k/ d% L, F* p) N( U
0 h. P% \2 c8 `! c% w
解题思路
" n  B6 [6 @6 O+ V2 i

* l2 \- o' ~( ~3 q% O! `* W: R输入的两个数组都是单调的,可以使用双指针。0 l/ a2 Y: M7 e3 j6 G; l
& s2 l% H* {% q, k
代码展示
2 {- h" o2 D' p
" A  V2 w3 ~! Q+ q4 ?& T
  1. class Solution {
    8 W, K3 T/ S; i$ Y: u( Z3 }
  2.     public int maxDistance(int[] nums1, int[] nums2) {4 I" d; Q/ T5 G" f& I, b
  3.         int n = nums1.length, m = nums2.length;4 R4 r6 F9 a$ c
  4.         int res = 0;
    . N$ n- M$ }1 N5 S( ]* X; B1 y
  5.         for (int i = 0, j = -1; i < n; i++) {
    2 m' [$ \1 F0 K( j. w! F
  6.             while (j + 1 < m && nums1 <= nums2[j + 1]) {
    . f- F$ S4 s# [
  7.                 j++;
    - B9 T/ Q+ U; n% l; H
  8.             }3 b* S7 X9 o/ I2 k9 w+ A% r
  9.             res = Math.max(res, j - i);$ G+ T( P( I4 h
  10.         }' w$ A% V8 g' f
  11.         return res;% m) u# g, `# d9 Q% H
  12.     }
    % j' g1 l! X" ~+ y9 k5 W0 A
  13. }
复制代码
0 f! |# T$ N$ @; i6 P7 X! W
No.3 子数组最小乘积的最大值
  y+ ?% P' E/ w9 `2 ^) c% C0 ~/ P1 f$ q
解题思路* }: v, `# F- {3 [$ L
- V% @: U9 ~, E
单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。
# S( M: a  j1 U5 u( v. ]* _) d4 H0 l7 q
当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。# a7 Q7 e7 q2 H- H' O
" p+ @) `! g* x! U+ L3 N
代码展示

" T7 j* s) F# D. I3 c# N6 R* u  L& Y4 c! E4 N/ K' {
  1. class Solution {
    5 M( i- S$ h" p! Z1 [1 a" R
  2.     public int maxSumMinProduct(int[] nums) {
    6 l( b0 _5 H% T% g
  3.         int n = nums.length;% |; {! f* S6 f$ C/ k( `
  4.         long[] preSum = new long[n + 1];
    ) f7 S0 Z3 r* \: ?  |
  5.         for (int i = 1; i <= n; ++i) {
    % M0 J- Z7 V- n
  6.             preSum = preSum[i - 1] + nums[i - 1];4 A* s) Q/ p7 O' U0 @
  7.         }6 Y8 C+ a3 u* q) E

  8. " I& G7 a0 L1 l9 [: Y8 Y
  9.         int[] l = new int[n];0 a# m8 ?+ T% G9 c
  10.         int[] r = new int[n];2 a7 p$ V& l+ K  G6 |
  11.         Arrays.fill(r, n - 1);
    : a1 p  w% B: A- U) G% Q
  12. 1 [* z7 p! w2 }5 Y; P  C
  13.         LinkedList<Integer> stack = new LinkedList<>();( @2 Y# A+ ~0 ?6 l
  14.         for (int i = 0; i < n; i++) {3 \2 Z) u& U% B- B0 h
  15.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {8 {2 M# s: X; Q' J" H0 W
  16.                 r[stack.pollFirst()] = i - 1;( u4 [; p8 w/ }% k2 Z  P
  17.             }% B+ F% T. e; u& n! y$ n3 t
  18.             stack.addFirst(i);0 [. W* Z7 ~5 D4 Y- z
  19.         }1 R& U$ r' t* L+ ?/ F9 _) x* ~
  20.         stack = new LinkedList<>();
    # }+ h7 l1 O; R$ O, a% o  C
  21.         for (int i = n - 1; i >= 0; i--) {
    0 `' W# ]) E; _# A1 c
  22.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
    8 f; a0 E' h5 b% r% d6 {
  23.                 l[stack.pollFirst()] = i + 1;
    6 j3 I) a( T# b8 s
  24.             }
    5 }& \* v$ g" W' Z! S7 q! Q# d* r  c5 g
  25.             stack.addFirst(i);
    7 q! p& E) c! |0 G+ u
  26.         }
    6 I" J: v, }3 ]4 W% U
  27. 4 x2 {* v/ W& g0 ?/ ~6 x
  28.         long res = 0;' j. h" d5 F% R3 ~( f7 r
  29.         for (int i = 0; i < n; i++) {6 o1 ?8 Z6 n3 b2 J& u5 p- I
  30.             res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);/ a5 H* b9 c& P6 g% U6 @
  31.         }
    ' ]5 J9 l: \  q$ a. `
  32. 1 [: q3 e( k. e! K! X8 Y6 ]
  33.         return (int) (res % 1000000007L);
    : o8 G9 J, s/ _! }# d  M; t
  34.     }+ Y: V0 G$ L; P1 V! a, A! P
  35. }
复制代码
' e) e7 d& k2 c& b  d) H! L+ W5 w) f$ j
No.4 有向图中最大颜色值
/ g: `) P- w8 W+ w: h, ~
: q' F$ Z+ `) e; f' T/ ^: y5 J解题思路
. C( T# S" }! E! @& W. w; w# I0 W& W0 b: b, t
先判断图中是否有环,有环直接返回 -1." x+ ^! d8 P" `: Q- W5 b% K

1 B2 k4 D8 e7 |1 s3 \( M* t无环的话则使用动态规划求解。
, x6 @& q7 l+ t. X, Q& i6 ?6 d5 v: I6 h5 }( |  X, L' Q
代码展示9 v3 c0 N# R! ^) ?" N9 P
. j2 o; N0 L4 n% C
  1. class Solution {
      d5 ]% w% ]1 z# \5 o5 s3 g# M6 k
  2.     public int largestPathValue(String colors, int[][] edges) {- V" w$ _; `9 z. U% O
  3.         // 建图
    : X, Z$ Q* j1 J+ H
  4.         int n = colors.length();
    # f. s" c& L2 K$ l1 J: O
  5.         Node[] nodes = new Node[n];
      m4 `' y2 g  S7 W* j, R% [7 d
  6.         for (int i = 0; i < n; i++) {
    5 e2 T! l: |% V( r9 X' M* u
  7.             nodes = new Node();2 i2 @9 {/ _1 [; C" E4 M
  8.         }" t8 l7 U" ]& A* l  h# N
  9.         for (int[] e : edges) {
    : ?3 J: z) o% B( ?+ U6 j0 e
  10.             nodes[e[0]].nei.add(nodes[e[1]]);
    , i9 D  N. m0 j1 _' }( U/ o
  11.         }
    4 y1 h$ v' I* v$ J# x$ j; T
  12.         // 判环2 D* r+ V4 Q1 M, y( z: n3 q. u. A
  13.         for (Node node : nodes) {$ Q# l) ?* ~1 W) }; a" _. E/ m: w
  14.             if (findCircle(node)) {) }# G# M1 X9 g- u8 Z
  15.                 return -1;
    " I" L0 T( Z" G1 ?  X& W
  16.             }- r7 l# D( O  ~+ }2 h
  17.         }+ y' u; [4 n7 A9 ~
  18.         // 动态规划7 H/ f4 p( m4 ~( b
  19.         int best = 0;( q& A5 }2 @- I  d
  20.         for (int i = 'a'; i <= 'z'; i++) {
    $ m: ?! m9 K' X8 I
  21.             for (int j = 0; j < n; j++) {
      T7 @- z0 q& v! b" c. ?2 P* Z( J
  22.                 nodes[j].dp = -1;+ {+ }+ i" J  f  O- `9 B
  23.                 nodes[j].val = colors.charAt(j) == i ? 1 : 0;
    : V3 Q$ V5 I. \
  24.             }& n- i% H3 W  M
  25.             for (int j = 0; j < n; j++) {
    1 x2 G4 w# a. [  e% S7 x$ W
  26.                 best = Math.max(best, dp(nodes[j]));9 h. J% s8 F1 N0 \
  27.             }0 C4 [( p6 V# }& t6 o
  28.         }
    3 G; g- {' T; w: a3 ~9 m
  29.         return best;
    % v* W! G- ]5 j' I) M3 Z
  30.     }
    8 N+ q3 a( z8 V0 ]+ @  F
  31. . t0 Y" A( m) }( Y5 l) M# b
  32.     public int dp(Node cur) {
    ! x0 h8 ?9 V; _1 m. s, C
  33.         if (cur.dp == -1) {
    3 l) Y1 W; c/ F& s; [: ?; s, k& Z4 r
  34.             cur.dp = 0;( d/ m5 G% B9 l
  35.             for (Node node : cur.nei) {/ x9 A( T1 o0 g# y$ H
  36.                 cur.dp = Math.max(cur.dp, dp(node));- q& U: [" t& i% A4 Y5 n9 o$ J" E
  37.             }; y3 {0 r+ ]: _% N' F
  38.             cur.dp += cur.val;
    ' I8 Z6 P! n+ z- _, i6 W8 S% ]
  39.         }
    / x1 b9 S; V) V  D+ X5 T- R' V
  40.         return cur.dp;
    % A* n5 E/ J$ `& X4 l
  41.     }
    ( d2 r6 [4 U7 Q) G0 W* u
  42. 7 `9 N! p' |, z. C
  43.     // 精简版的 Tarjan 算法:8 n# I! z1 ?! p) ?, \7 C
  44.     // 仅用作判环,而无需求出强连通分量
    . {4 k. P& {* `
  45.     // 所以并不需要真正使用栈,只需要一个标志位即可
    8 n% G& f2 l: [3 E2 R& |
  46.     boolean findCircle(Node cur) {$ E/ R* ^% b9 z) c
  47.         if (cur.vis) {
    . G2 q3 u/ x0 L' j  C3 {5 f
  48.             return cur.stk;
    5 Q4 o" y6 Y- F0 d
  49.         }
    ' m3 K: k; v% b; B$ p5 J
  50.         cur.vis = cur.stk = true;, A4 K( E$ H7 u2 z) G
  51.         for (Node node : cur.nei) {  N1 V# l# ^% Y3 ]( x: J  c; @
  52.             if (findCircle(node)) {
    7 \9 B: v3 w% l7 b. ^; B- i
  53.                 return true;
    + A* e6 V/ [! ^& X+ P. F) j1 v
  54.             }2 Z+ c/ t% o# g3 \
  55.         }
    3 v+ C. e6 S! p1 L% }8 i
  56.         cur.stk = false;
    * [, O  l. q+ {" l1 P6 h% u
  57.         return false;
    & l+ o3 c' \8 f  q' r. d0 K
  58.     }7 `8 [: H$ j' o, u- h" D
  59. }
    $ i7 Q/ O1 j# A

  60. " m& V0 [; [: e# B" ~1 E$ K2 M
  61. class Node {
    % o' q, `# ~3 T& ?8 h: W5 b; i
  62.     int val, dp;  ~! p3 W7 U/ e
  63.     boolean vis, stk;
    % C1 K3 k  [/ x
  64.     List<Node> nei;
    / h; I* ?5 J0 {; m+ `- v
  65. , M" l8 _; D, M1 p! o# y
  66.     Node() {" Q6 H; I; }; M. A5 @( V- `
  67.         dp = -1;
    0 H' G2 _6 Q; `1 a5 I$ ]1 z
  68.         nei = new ArrayList<>();
    5 Y$ a; W- T  F5 N0 ^. h
  69.     }
    # G, e( j* B- X5 X. _
  70. }
复制代码

. a* l; j% C  L& H5 d6 x4 D
' `' M( w1 Y& N* q5 c- Z2 R

本帖子中包含更多资源

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

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

本版积分规则

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