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

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

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

UWCSSA提醒您:

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

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

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

No.1 人口最多的年份
; I- n) @3 G9 H3 m8 C) v  z( _- Z' l( l
解题思路) Y$ z$ B, [: O- R" ^, N) ]
- g1 k3 \( {  X5 _  i* I0 f1 j3 L
数据范围比较小,直接枚举统计即可。
( V1 }2 W, {% u; w$ `
7 b- d! F* a( d, N1 F& v& E代码展示

  F$ R9 u! C0 q$ A6 j) e* `
  1. 5 Z$ R) M6 n. j( m
  2. class Solution {# p  b$ v- ]+ h
  3.     public int maximumPopulation(int[][] logs) {4 [" A6 _% x; q% i3 m- z
  4.         int[] population = new int[2051];
    : s& x8 j# G4 u/ t4 ~2 i* Q
  5.         for (var log : logs) {1 E* K6 [$ O1 `& d  k; P) f- N+ d
  6.             for (int i = log[0]; i < log[1]; i++) {
      X. v* c* \" `: B% B" f) }: d
  7.                 population++;
    : O9 K& \1 `  o% w$ T4 X& w
  8.             }& f; S1 P! T' v0 g
  9.         }# H; [- t1 B7 |3 f" N8 O8 E8 ~
  10.         int res = 1950;
    0 Q& s: I7 }* B& |* o: ~6 P
  11.         for (int i = 1951; i <= 2050; i++) {# E& V: q5 s6 }% O4 I4 }+ w. \
  12.             if (population > population[res]) {- o* Z/ V- E, C; T5 m
  13.                 res = i;/ s  N. x5 N& o- k: P- k% T
  14.             }
    * j, q& g$ d- r9 y  |" @) M
  15.         }+ K3 x/ F5 O' f8 z" [/ Q2 R  C3 L) q
  16.         return res;7 L7 z3 G# p  S& m3 g5 ?: u
  17.     }' r  X0 \: H8 j0 u9 a8 Z, h
  18. }
复制代码
" q3 ]. j  B" q3 j; ~/ @
. z/ u% J7 _- E' n4 l& K
No.2下标对中的最大距离
& q( I" ?# F: u; e7 R9 f% `- T8 E. Y3 i& l* Y( j9 H
解题思路

: l& k$ \4 F; D9 `' |; f
# Z( S2 a" k' f输入的两个数组都是单调的,可以使用双指针。" b5 E; T( U0 ?3 A

8 v% E  w; }/ `& d* Y. P1 F" w代码展示

( V% N% m) t- D0 f* Z6 N+ f5 }+ l
  1. class Solution {/ J) Y9 b/ x6 c/ s8 {$ O
  2.     public int maxDistance(int[] nums1, int[] nums2) {
    . f+ r* y6 B7 i
  3.         int n = nums1.length, m = nums2.length;7 ~. U$ _6 L) Y) _5 F2 d
  4.         int res = 0;- f+ z1 N7 T7 Y, z; S: g7 V/ o
  5.         for (int i = 0, j = -1; i < n; i++) {
    1 G/ `& _- @' j+ n$ b' U
  6.             while (j + 1 < m && nums1 <= nums2[j + 1]) {
    & `+ V, B* Y6 ^$ B
  7.                 j++;, \3 o: `9 C5 ]1 b$ n2 ?
  8.             }6 r7 s% \0 e+ s5 Y- Y/ E6 k5 T
  9.             res = Math.max(res, j - i);
    8 N+ H, C8 B5 k
  10.         }+ |2 e! r6 W% h) @' o$ D# b
  11.         return res;
    1 L: @( w5 @6 R' P! a8 f0 D
  12.     }, k' J9 O% r$ y# d5 ?
  13. }
复制代码
% {' X% X- {' X- ?' W/ i
No.3 子数组最小乘积的最大值
& k% Z; `+ F6 f  U# m
; e* s' `) [. H+ d; C解题思路
3 n5 A- u+ ?2 C6 a  D  [; P( o
8 r( X9 K+ V: ?3 L$ |+ V0 N单调栈的变形,可以先去做一下最大矩形回顾一下单调栈。3 J3 c% C- W1 }0 ]

3 H% v; d9 i* j- h) J) y当子数组的最小值确定时,肯定是数组越长越好,所以我们需要知道每个元素左右第一个比它小的元素的位置,以在枚举每个元素作为子数组最小值时,这个子数组最大可以是多大。2 d5 f) l% D# h: ^6 j- u6 H  c0 g; I

- ?- r6 T, E  N/ R& U& N  M- i; m代码展示

, C8 k0 P$ F1 s- l9 q* z  w# c) H; Z8 m0 @% h2 I2 ~
  1. class Solution {7 X% R' u9 |$ o; d6 I" l
  2.     public int maxSumMinProduct(int[] nums) {
    & Z% N  _7 T! W$ P& L2 `! W- Z2 a! p
  3.         int n = nums.length;
    . v7 v; A( k* O5 G0 \+ o
  4.         long[] preSum = new long[n + 1];
    0 e* Z& R  Z, t, Q2 J* P
  5.         for (int i = 1; i <= n; ++i) {) [; w& b' d% ^0 }) }7 u
  6.             preSum = preSum[i - 1] + nums[i - 1];$ l4 k4 c( b. U: R) `2 E
  7.         }
    # ~# h5 G! i' @- z
  8. / i  o* F/ t& m: a; A
  9.         int[] l = new int[n];5 B. t9 {) P* |3 [1 ^: m( _( o" Y
  10.         int[] r = new int[n];3 L. S3 \' O( P. `/ P2 J
  11.         Arrays.fill(r, n - 1);
    7 \7 h( Q% V) l3 u& Q7 {" r
  12. 0 V9 }6 g$ Q: U2 D2 n
  13.         LinkedList<Integer> stack = new LinkedList<>();
    ' l; T5 e3 o$ M' z- u
  14.         for (int i = 0; i < n; i++) {
    & `6 ^! z/ F; [. e/ v& R0 ^/ y8 L
  15.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {
    ! `) b( N2 G' L0 r4 S9 x5 A
  16.                 r[stack.pollFirst()] = i - 1;
    0 i5 B' Z( c" E% L- m4 B1 |- X
  17.             }2 a6 l$ Z% J: D/ c7 S- r
  18.             stack.addFirst(i);+ L0 J2 ^" r% P% c/ I& l1 N
  19.         }3 }" w% u1 h- f4 |- F( h4 @# K2 X
  20.         stack = new LinkedList<>();% f: p8 _: }9 v4 @; T
  21.         for (int i = n - 1; i >= 0; i--) {+ Z/ ?) ?, l/ ]5 \: |% r' e
  22.             while (!stack.isEmpty() && nums[stack.peekFirst()] > nums) {" ^5 z7 d* N1 }: o; O" ~- C
  23.                 l[stack.pollFirst()] = i + 1;
    1 P4 N; x/ Q3 ~! R5 i; p( L
  24.             }
    2 L9 |( f+ ]" S
  25.             stack.addFirst(i);- @, R8 z0 X  A6 m
  26.         }
    7 A8 X2 |/ q) L- e

  27. 2 L. t* D* W6 v! j
  28.         long res = 0;
    # y  T2 D* H1 ?7 d
  29.         for (int i = 0; i < n; i++) {  x! G8 d( |' n( B+ Z
  30.             res = Math.max(res, (preSum[r + 1] - preSum[l]) * nums);
    7 J# K7 S2 C$ q6 Z; Q
  31.         }9 y0 u. s* Z; E+ L0 O3 d1 u

  32. + G7 k9 d& Z  j4 T
  33.         return (int) (res % 1000000007L);+ j0 s# K4 T3 ]# X
  34.     }% G4 F! s# W# U  P' o5 T. y
  35. }
复制代码
2 {5 Y' [8 r/ c$ [
No.4 有向图中最大颜色值
- Q. u9 e/ M1 }7 x4 I% D. z/ e  p. `2 D( t) W
解题思路9 o/ w$ y1 E, `5 r
% c% j3 r% k; \
先判断图中是否有环,有环直接返回 -1.  ]7 w7 f* G- \$ Z' V3 ~, |
8 F1 V6 [0 D; Z0 S
无环的话则使用动态规划求解。
; k9 F! g9 `( Z! F6 T8 F) q6 ?& ?
代码展示: G  u2 d" k% A4 _3 I, ~) s' r

  V6 W/ x- M9 c1 ?
  1. class Solution {
    . T- K! U/ R  R  Y+ {
  2.     public int largestPathValue(String colors, int[][] edges) {$ d/ z" s8 E+ F/ m8 A
  3.         // 建图1 U# y$ M( M0 B1 @% J
  4.         int n = colors.length();
    , d: T7 `; o5 B' E
  5.         Node[] nodes = new Node[n];  P7 g0 Y; d; n  ~0 w) C
  6.         for (int i = 0; i < n; i++) {7 o  s) w, o, q
  7.             nodes = new Node();
    9 Z2 M2 w7 ]* L/ M: l8 G9 T+ y
  8.         }' F8 M0 S; |3 R  c/ g
  9.         for (int[] e : edges) {" K+ v8 `$ c) V8 _$ m; o( R
  10.             nodes[e[0]].nei.add(nodes[e[1]]);
    , G) {. a0 a  u. i
  11.         }1 H* p' D  z, k9 C; H
  12.         // 判环
    ! a7 n2 F/ M2 T' u
  13.         for (Node node : nodes) {
    * s7 t1 C7 j1 E) q
  14.             if (findCircle(node)) {+ \% ~7 D5 ?, N2 w! a
  15.                 return -1;" D. H$ A* Y" s3 V1 L/ Q. W
  16.             }) ^+ q7 L0 e4 m% ?5 k2 m; W% B" U
  17.         }0 Y; W1 w/ T& T% k" v) Q, m
  18.         // 动态规划
    3 Z7 E  |5 k- b2 Z# O# p
  19.         int best = 0;
    % c1 J6 i+ x3 \+ Z0 \4 |# `4 a
  20.         for (int i = 'a'; i <= 'z'; i++) {
    - ?' s, @0 e# C" s2 P! F( B/ C
  21.             for (int j = 0; j < n; j++) {4 I/ V. J7 s2 W3 v: s, k
  22.                 nodes[j].dp = -1;
    " L# b# L4 M' u0 b- g( H7 i
  23.                 nodes[j].val = colors.charAt(j) == i ? 1 : 0;+ i6 ~8 t! P6 Z, d
  24.             }  ^8 `4 K2 n& O
  25.             for (int j = 0; j < n; j++) {
    % ~5 d9 W% ?. ~
  26.                 best = Math.max(best, dp(nodes[j]));$ |0 ^2 ?$ ?3 G5 ]8 G; f
  27.             }
    3 R" Y+ G2 s- [' c9 @3 J( S0 I! }
  28.         }
    & w$ q/ H" P6 r9 ~
  29.         return best;. D% c" R. U5 t7 f4 a% H$ f
  30.     }
    ! n% h8 ^/ H$ U; R4 h- E

  31. . c; F% i6 K# ]* Y
  32.     public int dp(Node cur) {
    4 I1 P0 E; u8 n9 d# b8 R( a
  33.         if (cur.dp == -1) {/ L. t, h: ?2 G+ G
  34.             cur.dp = 0;1 Y/ N. j/ Z) m' r; d4 m
  35.             for (Node node : cur.nei) {
    4 b4 u, M6 {0 G  s
  36.                 cur.dp = Math.max(cur.dp, dp(node));
    8 ~! G5 R; ?0 P  S; m2 [4 Q
  37.             }
    , {' l# u: h* m; A
  38.             cur.dp += cur.val;
    : D8 W. l4 }! T4 W+ K9 Y
  39.         }& s* [3 W8 O  s- i
  40.         return cur.dp;
    3 e/ r8 S5 I! `* U, l8 |
  41.     }
    , i, }) X, d' k2 Z
  42. 8 X8 s- n1 j& ~2 e2 @1 j  l5 A" E
  43.     // 精简版的 Tarjan 算法:
    ' ^( ?; S1 D4 t; w& W% K, h
  44.     // 仅用作判环,而无需求出强连通分量
    - i3 v; O. {: \+ f
  45.     // 所以并不需要真正使用栈,只需要一个标志位即可
    * W" U. B  m4 A+ b8 k4 Q! c+ [
  46.     boolean findCircle(Node cur) {
    ' K! }' Q8 j0 O: V! c
  47.         if (cur.vis) {$ o8 T$ x+ g" z, v: D
  48.             return cur.stk;* a6 r! e+ U; v* s
  49.         }
    & v" B; a+ a& r7 a
  50.         cur.vis = cur.stk = true;' }& o# l1 a8 w% ?
  51.         for (Node node : cur.nei) {/ ]" ?$ W# j4 \; W3 D
  52.             if (findCircle(node)) {0 K/ `4 |. A. c/ p2 F
  53.                 return true;! F' P! b$ N3 `/ V0 l
  54.             }5 q! l" L% e. q( r' z
  55.         }
    & w  X" K0 ?; g# [
  56.         cur.stk = false;
    + ~( U4 K5 d6 y* Y. O5 K& [; n" x
  57.         return false;/ z" l. k1 P9 g- B: s
  58.     }
    , R/ q7 G! |" ~6 d
  59. }
    7 d4 b1 R5 w1 e  Q5 d* x- t" e" q
  60. 8 H- _9 E7 x  v0 K: A8 g( c
  61. class Node {. y5 I+ x+ ?5 e3 K! y
  62.     int val, dp;
    , q& @6 X. Z/ I# M; e- i# K& h
  63.     boolean vis, stk;2 d1 [* o2 M) S% S- Y7 W
  64.     List<Node> nei;
    6 n9 o: y2 P* p5 y, J" F

  65. 4 G4 W2 U1 s! F  Z+ s! N( ^5 y: h+ e
  66.     Node() {
    + W1 z( |+ C0 ~
  67.         dp = -1;
    6 O% {6 X( W: t- b
  68.         nei = new ArrayList<>();# q* H8 D3 U- w6 t* t0 ?
  69.     }
    ' W+ u1 k* ?0 j4 S
  70. }
复制代码
" ]2 T4 E( @1 h+ ], N
0 ^% y( R; D& Y- q7 Q+ m" Q4 b

本帖子中包含更多资源

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

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

本版积分规则

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