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

[吹水聊天] 上岸算法LeetCode Weekly Contest 286解题报告

上岸算法 回复:0 | 查看:1845 | 发表于 2022-3-27 16:58:22 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出两数组的不同】
: x0 n$ t! z3 H* l
+ ?. Z8 A5 j2 M- _' p. O解题思路( c  ]! N# H5 k: W' I3 S
可以使用 sort + binary search 求差集。
2 G  O6 x( v, X% U9 E
" t& p* z1 x/ k代码展示. r, q8 g8 \) Y! h4 Q9 F& y

- o+ A4 A1 A& E, tclass Solution {8 R6 B5 j2 ^0 F- p1 m% J
   public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {, g7 w$ t" `. H- o3 Y
       Arrays.sort(nums1);
2 u( C5 r; N- \- V3 q( D       Arrays.sort(nums2);
5 ^& N# I+ x# B! C       List<Integer> res0 = Arrays.stream(nums1).9 n0 |# s0 R4 @4 Q
               filter(i -> Arrays.binarySearch(nums2, i) < 0).
& m) W! |) ^- R# N4 u& h( G               distinct().boxed().collect(Collectors.toList());' [' `% C- P2 z" C, Y
       List<Integer> res1 = Arrays.stream(nums2).
1 w+ c" e$ U0 L               filter(i -> Arrays.binarySearch(nums1, i) < 0).
  u1 d4 B: S# k% V9 P# ^: w1 Y               distinct().boxed().collect(Collectors.toList());9 L# p6 ^4 t8 Y7 \
       return List.of(res0, res1);
" |1 |, s7 ~/ U2 y8 @1 W. u  }+ t7 X! Z, F1 b3 h* T
}
4 g0 E* F/ z! t/ M$ b% U; i8 Y6 u: s$ L5 w  ^+ Y6 @
- d5 L4 u4 e9 f1 }8 t
【 NO.2 美化数组的最少删除数】! a2 \1 Y. {0 Y8 Y9 k

3 t5 H4 F  G% B' v3 U解题思路3 A3 D3 s) P2 y* [4 l5 E
从左到右遍历即可。
0 G/ S/ F* t8 l2 k" U( s8 U; e8 i4 Y( A$ K) x  G
代码展示* n0 C; b/ D- X7 z+ T" D2 }
- \7 W! x7 @; J6 c( |
class Solution {) p# o& q. W1 Y( V/ @- ^0 b4 C
   public int minDeletion(int[] nums) {& \) a0 g$ M6 P4 `1 a# I8 V/ ], [( L
       int res = 0;
4 g/ r0 Q. U6 ^7 |% @       for (int i = 0; i < nums.length; ) { // i 应当和 i + 1 不同
  s+ m9 w7 S. E! D/ ^9 q           if (i == nums.length - 1) {     // i 是最后一个,应当删除* {2 O0 L4 _4 H8 q
               res++;
) [# ^  p" {+ |- R( a( s2 k+ \               break;
, x# D9 O; @5 _" g5 J7 Q          }
8 ?7 i* c( q$ c# x           if (nums[i] == nums[i + 1]) {   // i 和 i + 1 相同,应当删除,相当于 i++1 B7 ?2 K/ e3 Y2 X1 s; ?
               i++;$ Y2 _$ `, q" ]( v* `' l
               res++;/ r; V- m7 h0 \: f, E9 Y. M$ F
          } else {                        // i 和 i + 1 不同,可以保留,i += 2 以判断下一组
" d  V3 [9 \$ Z! k, P; ]$ A7 f3 ^7 g               i += 2;
! K, r, r8 [- E) @+ a) n          }
# [* f. r4 f: s& _8 k" a8 D; l' z      }
* S, N# ~0 L6 `. x. }  c  x: m$ ?9 c       return res;( r9 b: s- h; N3 L- l
  }3 ]; j/ _  D5 d- h$ e$ A
}
$ U/ Q0 p% s7 w! D
5 o/ b( |: Q7 Z1 O4 S, F
3 K% t$ q' j  O, q- g- @7 s【 NO.3 找到指定长度的回文数】; b" n' U0 G: e3 M+ C; g
, b' o, J3 H& ]* g2 ~% }
解题思路$ v+ a* j* U: M
举个例子:长度为 6 的第 k 大的回文数的前半边其实就是 100 + k - 1,由前半边复制出后半边即可。
$ o4 @" X2 m" M2 j. C! _$ e6 O& p7 g( `5 r- y- d
奇数长度的回文数在复制出后半边前去掉末尾数即可。
  V( U& E& a" V0 g# q& ?1 r$ V% k5 P. [# j% U  i4 b
代码展示. a* U1 W5 V" ?" K( w2 o  k, }' G: `

, w! m9 u3 B2 I/ `0 dclass Solution {3 k) Y. P) v+ N1 Z2 g
   public long[] kthPalindrome(int[] queries, int intLength) {$ m) @! u8 m( u
       long[] res = new long[queries.length];
3 }" ^# g; P& P8 k2 u( l       for (int i = 0; i < queries.length; i++) {
/ e7 A- t9 z9 g( z; a$ s           res[i] = kthPalindrome(intLength, queries[i]);
7 d* G! W4 _' W$ W8 C  [; N      }
# k+ ~9 r) M2 a       return res;' }: f6 j- }* [
  }
3 ^- e0 @. \2 K6 u7 w" ~
2 C- B7 {! o0 Q) T3 L: r   // 返回长度为 intLength 的第 k 小的回文数
# q6 a3 T1 C1 K+ M   private long kthPalindrome(int intLength, int k) {7 {, V% F5 A$ n" Y  K
       // 处理偶数/ p1 {9 ?7 l5 O0 c4 B3 g
       if (intLength % 2 == 0) {
) L" ?, P$ f3 `; p9 e9 v           long half = pow10(intLength / 2 - 1) + k - 1;) ~/ P( J3 R% p' @
           if (length(half) * 2 > intLength) {
4 s9 }6 L$ L( g) c& U9 j               return -1;1 }/ H# d/ b: G# j1 o4 I
          }. z4 ^9 P: B; ]9 X: ]' [
           long res = half;, R  Q# d, H+ B
           while (half > 0) {5 f& X3 ^( ?& @" g/ J5 \
               res = res * 10 + (half % 10);, j# J0 F# e0 k- V/ ]: t, @, Q3 e$ X
               half /= 10;& K) L* P, A# ?* p
          }
- F! c- j  j( K- ~  k9 E5 ], w# ~           return res;4 Y; m# l: ]8 z* g6 x
      }
) K9 T( m+ S0 t* P/ t4 r$ g2 _* R9 F7 c3 r
       if (intLength == 1) {
3 [# l. Q3 Z6 z8 }6 s& W           return k > 9 ? -1 : k;
: A/ S- z+ n& K, h      }4 X9 ]/ u) X$ Y' U$ a8 I8 e

% Y( c1 `6 L3 |9 j0 m       // 处理奇数
. B' U* Y) G" g2 d% f       long half = pow10(intLength / 2) + k - 1;
# K8 l+ l0 t% `' b       if (length(half) * 2 - 1 > intLength) {
- y, `/ `, E+ ^' }           return -1;4 {. Q' v. t" \4 b' t4 j
      }& t0 L4 ~; H% k- T$ [8 s( c( L' p& ~
       long res = half;
3 V' h- m' R9 [+ u( h* [       half /= 10; // 去掉末尾数- n# a' K9 V; U( S9 G
       while (half > 0) {' u/ g7 q! X" V+ h& X
           res = res * 10 + (half % 10);
) x2 n# d6 h1 r# y           half /= 10;
/ ]0 e, X4 O. I8 q  @) H, W      }) h; y  l/ a" b# g
       return res;
/ Y: [" _: |2 b: G  }
, L. j* t4 G* v, f* ~9 |- V
& h' ^: N; o' v/ v3 z+ q- n: o* k   private int length(long n) {& S# k; D1 g6 k. V8 Q
       int res = 0;, ]: u/ |$ ]/ B: w4 q
       while (n > 0) {8 |4 p/ l3 p( {) S: C5 @
           n /= 10;
$ w# @& \( K! j& b3 L+ r1 }           res++;
* T) d8 y9 }' @3 f$ V4 M/ k0 U- J      }' v$ A* |4 ~! h; l% o# }$ @
       return res;
/ O3 W2 i2 W; ]! x' Z7 Y/ \  }% J6 |5 k/ _. Z9 Z6 p  s
* Q0 o+ u2 B7 b) A' F) i
   private long pow10(int n) {
9 d2 _; l/ }  m* w& R2 i       long res = 1;
* t8 k, p- k, x2 E9 b       for (int i = 0; i < n; i++) {& q3 f3 t' U" Y9 {4 O" V. Y8 m
           res *= 10;
9 q0 I; ~" a# w# R9 E2 ^      }0 U# ]  T! N$ Q2 u/ f; n
       return res;
# u$ n! d$ g' [' L' y  }0 |5 X1 O* u( C' b& {* @' u
}* s2 x. S8 q6 r2 f- a' c( z7 Y$ l
8 _4 J& g; ?! l& m, h  s2 Y

% k8 t) T; l( h- p【 NO.4 从栈中取出 K 个硬币的最大面值和】) a( Z& C9 P% A* f, U  R9 h) m
, `5 o9 Q' ^0 l$ O. j% ~' }  [' v
解题思路
; C5 ], x3 K6 Y9 C典型的动态规划问题。
- R: n! z% T0 G# B) Q+ N# w9 d; x/ a* |, ?% I$ ~/ O
定义状态:dp[i][j] 表示前 i 个栈取 j 次得到的最大和。
: Q4 e  F5 k4 E% U( s+ t. D, |
9 W- j3 A, D8 l: E: P( {# r4 u2 F状态转移:在第 i 个栈取几个,即 dp[i][j] = max{dp[i-1][j-t] + sum(i, t)},其中 sum(i, t) 表示在第 i 个栈取 t 个硬币得到的和。  Y% f8 E% _- j5 d( p( {' Y
# j0 H8 v/ f5 E- C
代码展示9 r8 h5 W3 c1 |2 K  g9 i' M

7 A. o6 l: J2 [$ i( C5 [class Solution {4 s2 X& ~1 O; P6 ^# Y  Y  b* ~" f2 k
   public int maxValueOfCoins(List<List<Integer>> piles, int k) {) A- B+ f# f0 n1 K
       int[][] dp = new int[1001][2001];
- T& ]  m: G7 g       for (int j = 1; j <= k; j++) {; n/ F& j6 {) C! R3 \
           for (int i = 1; i <= piles.size(); i++) {" M0 E  Q: b5 P4 P# d
               var p = piles.get(i - 1);
4 ]8 r( _+ u- a! `               int sum = 0;0 O8 e3 t/ z" X3 B# y" S' Y
               for (int t = 0; t <= j && t <= p.size(); t++) { // 枚举在 i 取 t 个
7 `6 Q4 b, Q' y4 L                   dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - t] + sum);3 `2 I0 t- I& Y
                   if (t < p.size()) {
8 p" c( i. F; P% l+ H+ y                       sum += p.get(t);
+ W8 W8 g) L+ ?: ]7 @3 c* d                  }5 y& w3 h4 U, y3 }1 F& u0 ]2 U
! C! ?4 b0 x! i8 g
              }2 U0 @8 x7 @& g9 d/ G# E8 Y
          }! c. e1 U5 p: ?1 F$ \
      }& i5 c' b' m& B  q6 R& [
       return dp[piles.size()][k];5 m' o+ g: b# U9 u3 D- m
  }8 a, V& P! s  T. ?; j
}
* S2 ^( P" _5 X" |) k' ^' H
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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