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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出两数组的不同】
. a  y+ R5 Z- V( e& w, X3 e# J+ c+ n: M: b" X3 t3 F; x
解题思路
: j( t4 r6 }1 g/ L8 B可以使用 sort + binary search 求差集。0 h% W( J( m( D/ m

1 D! G2 L# |. `1 H8 M代码展示9 Q/ h; ^5 L' r1 b  E# A
. B& u1 G' n" Z% L
class Solution {
. ?3 Y* ^& I7 |: O   public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {: E0 y* @1 S, G" N2 N. q7 y, @9 a
       Arrays.sort(nums1);/ C" g' f* L8 `3 T3 ]
       Arrays.sort(nums2);6 o4 L8 p4 ^! L6 H( ^* ^
       List<Integer> res0 = Arrays.stream(nums1)., B. d; }" F! _3 c: p% z2 M
               filter(i -> Arrays.binarySearch(nums2, i) < 0).
  G1 w8 u3 d! i. [               distinct().boxed().collect(Collectors.toList());, ]3 J2 d& Q$ q# }. E2 O
       List<Integer> res1 = Arrays.stream(nums2).
' S& O+ ?# U+ ]0 [- J               filter(i -> Arrays.binarySearch(nums1, i) < 0).3 C: e) j  k+ S9 a' b1 P( F
               distinct().boxed().collect(Collectors.toList());6 ^2 i- n" k0 ?5 y7 H
       return List.of(res0, res1);( L5 z# L2 o6 S" N! o
  }: |* {: S( I! @5 p$ \& J
}) \1 c9 [. t6 y8 i+ ?
& U+ k- D8 p- A2 M
. W+ S* ^' [% K4 l5 B- g
【 NO.2 美化数组的最少删除数】( C5 v8 x/ ?, u! u7 f( `
  R* M4 s5 r# q! N9 l
解题思路
% N! f6 _# o: {' w8 m从左到右遍历即可。
; f* S  C2 i* U9 ^% [% |( x) |5 S6 L1 o" b: u7 G" J: r
代码展示
# C0 O6 P% b# t) K5 T9 ^( B2 @+ \
/ `- a! C: Z, N0 d" q! P$ c2 L$ vclass Solution {' \1 T4 }1 q8 N3 V9 g3 V9 P6 N
   public int minDeletion(int[] nums) {( [4 K, Z# j6 q1 M
       int res = 0;
* S4 `4 I, W8 F: o: C+ e: i2 M       for (int i = 0; i < nums.length; ) { // i 应当和 i + 1 不同
  d; S: R+ Y' e' t6 V           if (i == nums.length - 1) {     // i 是最后一个,应当删除
/ B& H0 T$ _0 @& k4 H; G1 a               res++;3 |5 z2 T0 \3 j* p( o6 P% R
               break;; ]4 @) L6 i  \! ]/ z
          }
2 X) S7 r$ D8 G6 W; m           if (nums[i] == nums[i + 1]) {   // i 和 i + 1 相同,应当删除,相当于 i++
* S7 l) T3 v( k) R               i++;
2 c; I' K/ x4 ~4 {: d               res++;
! h$ l$ M3 G9 A. [$ \          } else {                        // i 和 i + 1 不同,可以保留,i += 2 以判断下一组6 `2 o( p' ]3 [& \% ?
               i += 2;
- w" C, G  y1 d          }5 [6 a6 M' U) n$ B& G7 N* X1 d% L
      }4 L( b) R; f. G0 i* R$ @- x
       return res;5 R- s  _; g8 n  t6 X! X; ^9 U1 U
  }
/ v" M, I) g! W0 I- C5 w2 V$ I0 ]}: l; z6 @# y2 Y
7 D+ i6 i- q/ K5 f
3 ~) t# j1 ~& f9 `  L* K9 ^
【 NO.3 找到指定长度的回文数】
8 R% Z5 j8 @8 T$ ?! Q# V& L7 N/ I" P6 W! q
解题思路$ H: |8 P' [. z) q: u' r
举个例子:长度为 6 的第 k 大的回文数的前半边其实就是 100 + k - 1,由前半边复制出后半边即可。
+ D( }9 q6 O  i5 v
: l' ?3 F5 f* i0 e9 k奇数长度的回文数在复制出后半边前去掉末尾数即可。
# u3 o- q9 a0 e
4 F* v, o) |3 \# N. E* ^' Z/ V  j5 q代码展示
. c5 X* |5 Q2 r1 t
( f2 c6 s0 h" c0 k! N7 Iclass Solution {
0 X/ {" E/ X/ n4 J  P# P6 ]/ R   public long[] kthPalindrome(int[] queries, int intLength) {
' U- l2 n5 q0 n. f& m       long[] res = new long[queries.length];
; N& ], {6 |% y$ E" _. X  Z9 d       for (int i = 0; i < queries.length; i++) {
  r& u$ c. u* f- @' y0 [           res[i] = kthPalindrome(intLength, queries[i]);$ a! z( F( o6 `5 F' G; _
      }
( m0 X6 K1 l2 l3 b       return res;' N! w" t' A& G4 Y5 R. N$ S$ m
  }0 o  U/ b7 E- g( R( `8 t# b" I% |4 W

; f9 ?2 g7 Q+ h$ S$ O7 Z0 V   // 返回长度为 intLength 的第 k 小的回文数. w! l' l2 {+ X: d( v+ {) ~8 Y: i
   private long kthPalindrome(int intLength, int k) {/ N% ]2 U  h- m  k! l/ W2 w
       // 处理偶数
  {  P  ?( `$ Q9 [0 ~  c8 o8 w1 |% L       if (intLength % 2 == 0) {  L9 c- U/ P- G/ G
           long half = pow10(intLength / 2 - 1) + k - 1;4 J2 o. _0 A- b0 D4 z! p
           if (length(half) * 2 > intLength) {! o5 A* l! b: t) t, y3 {
               return -1;
+ h, L, M6 q6 d/ V7 f          }  R7 z' G% V2 l: A! j5 q
           long res = half;6 }4 ~! I" K  c( W$ D# `/ B/ R
           while (half > 0) {
$ j5 J2 L8 i* C8 ?4 f  K               res = res * 10 + (half % 10);
- q5 x9 q7 b5 _' s8 u% T               half /= 10;5 K" `0 t- ~, p6 `! L
          }( A8 u) z% R0 I& b$ W1 v
           return res;
* s4 J7 e8 k) K) I6 r$ C. Q! K      }% C( i1 W' N+ y  ^) B- A. s
; X: |: l/ }* X. F# C
       if (intLength == 1) {
& ?: t/ X* ~4 m9 j           return k > 9 ? -1 : k;
$ }# E8 C0 t- m  N      }
% x1 I5 s1 W5 H1 e" X# D: D( k9 g9 o2 q$ N. j9 `! \& ^
       // 处理奇数
# L5 l, }; d4 }4 F! ]: L/ h       long half = pow10(intLength / 2) + k - 1;
5 i* J/ j3 V  `       if (length(half) * 2 - 1 > intLength) {5 X& D/ n6 M( i1 N
           return -1;
/ h9 Z+ n) _. I+ D% X1 `      }- f. r6 p% y* P' J0 n
       long res = half;) @+ T( h7 J1 W1 z" {2 e
       half /= 10; // 去掉末尾数
8 V. {& c" F6 G7 a% `& j       while (half > 0) {% h* Z: b& Y& l$ m& a. o
           res = res * 10 + (half % 10);
. r) F' J/ Z1 J# k           half /= 10;
* V: P( h1 ~. E5 J! R1 \. ]9 |% _8 v      }
7 y3 Q+ f/ o" I2 W0 @/ w       return res;
5 [4 V8 M5 Q5 ?* ?0 e  }$ o7 K$ r$ Q4 E' C# O% P+ r5 A
1 u! x" v$ [7 M1 S% V! _
   private int length(long n) {$ b0 m2 g  n, r' M' f+ ^
       int res = 0;1 k7 |# _0 J6 w" p+ ^
       while (n > 0) {8 n% [8 ~$ S4 r2 ~$ W( L& g
           n /= 10;
  @/ m9 H# ^) ^+ L           res++;
6 a' z! L0 m; K/ }      }; J: X1 n* Y4 {# N2 j& Q
       return res;3 @5 z8 c1 S) b, f
  }0 p1 P+ r& I! C  s9 T4 Q% H1 ]3 B9 v9 h% r
* j7 ^) h7 q3 b2 M+ K; u3 B
   private long pow10(int n) {
+ R0 \  i! u" g. p       long res = 1;
" V+ C; g7 a% i8 t6 c% `       for (int i = 0; i < n; i++) {
- |  S; y( ^5 y" b/ ?           res *= 10;
6 `7 R0 w5 y4 o( ~, e) b      }
) P6 Z" {6 @- l0 S) K0 q       return res;1 R1 r; Z; K: p" S; O: v1 g2 O
  }' B, z" c0 G0 G: E0 \1 j2 P
}
$ u$ X8 G7 c/ ?: V
2 v( L! |  V! C/ A8 @2 e7 y9 h& r# [6 l* _- e1 a; I4 D: U' V! k! O- i
【 NO.4 从栈中取出 K 个硬币的最大面值和】
- H0 Y' u- ]' R4 ]5 o$ b( c$ Z& L7 k  C% l. Y4 e
解题思路2 g, f! l  g# t. @# _* Y
典型的动态规划问题。
7 ^% ?; V1 Q8 K) v! n$ A1 P$ o+ l0 M! L: `) [( l) l) N5 e
定义状态:dp[i][j] 表示前 i 个栈取 j 次得到的最大和。% f. ~/ M; f: T/ m
6 P; s# c% D$ G8 A5 Z! H
状态转移:在第 i 个栈取几个,即 dp[i][j] = max{dp[i-1][j-t] + sum(i, t)},其中 sum(i, t) 表示在第 i 个栈取 t 个硬币得到的和。5 y( {, i8 r; c3 j2 Z7 L
8 T: v* z* w/ _6 ^" J4 O6 Q6 d
代码展示4 e+ l& x2 W" h( }
+ ?% g* Q1 ]; u9 R! U, X2 Q0 P9 l
class Solution {8 r4 n7 p1 l$ v% \1 W) G/ i
   public int maxValueOfCoins(List<List<Integer>> piles, int k) {! g$ n( M  C0 C# X/ K
       int[][] dp = new int[1001][2001];/ z* r. K  w6 X
       for (int j = 1; j <= k; j++) {
: M8 E6 {8 Z) ~$ u( v           for (int i = 1; i <= piles.size(); i++) {
1 x2 f2 w+ t: C+ I/ W; A3 n* ]& m               var p = piles.get(i - 1);
2 S( M9 J/ q7 y3 A' _/ J/ m& z               int sum = 0;2 t2 i% H- d! L/ P
               for (int t = 0; t <= j && t <= p.size(); t++) { // 枚举在 i 取 t 个
5 y* z3 A8 o# Y                   dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - t] + sum);
' A! l. f* \7 R  \* w, l- N                   if (t < p.size()) {
) r4 t" }7 k- y                       sum += p.get(t);3 Y  @! X7 m) k: m8 h( {
                  }
' [6 R- n5 Y5 M. v# j2 w) y) a5 {) c2 S( i
              }
3 ^* [, k& N! Y: y          }- t% [4 d7 [6 \1 }6 S: e( `
      }
$ x5 i) E( i. j4 U: W7 Z       return dp[piles.size()][k];
9 m/ E5 A( A! Q6 F4 u" V6 [  }( @8 M* w& y# n( Y# i0 r
}
# l7 s2 u. ~$ @
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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