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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 找出两数组的不同】( S! {7 Q+ m& O4 ]5 t( J
( D6 j$ O0 F& e+ x1 j( e
解题思路
' R: U1 w9 n; E) d6 J可以使用 sort + binary search 求差集。& Q' J0 [9 Y7 ?9 O

2 h# v/ t/ O! V+ ]% B' J代码展示
# G1 V2 N; s7 K8 ~2 U$ t6 X' Y, X2 v/ S9 C5 F9 @; r0 O$ E
class Solution {
6 M* `# R: v6 z; P8 S" e   public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {
6 O7 n4 S9 O- ^% o       Arrays.sort(nums1);0 d0 n9 p% Y  L  E$ {& F3 G$ k) F
       Arrays.sort(nums2);7 w( c' f: q4 v# B3 R/ E
       List<Integer> res0 = Arrays.stream(nums1).. d3 `" i8 z* L0 C% }
               filter(i -> Arrays.binarySearch(nums2, i) < 0).* r* p6 z& Y% E) N/ ?
               distinct().boxed().collect(Collectors.toList());
" E# w: Y8 U6 V       List<Integer> res1 = Arrays.stream(nums2).' E0 X# V" e8 f
               filter(i -> Arrays.binarySearch(nums1, i) < 0).8 J- J9 G8 P! q% {* Z
               distinct().boxed().collect(Collectors.toList());
- u, P( e3 o4 h$ A, S/ p       return List.of(res0, res1);- E. H. Z7 g$ ~8 {/ J
  }5 U/ {  s; w% E, k% T& V5 V, G+ B
}
$ b. n0 M  o! P) K, B% B  E( ?( q# P+ J; j8 L' J, d3 F5 h; @5 V

4 Q+ l: Z- D) F【 NO.2 美化数组的最少删除数】
- J8 Z: ?" ^: p4 f; [0 k9 L0 ~# L+ Y& o; y; n" Y+ |
解题思路  q! i: w+ G+ J% b# t
从左到右遍历即可。
4 M3 t) Z/ j+ k' \. a" ]. n- |* J0 q; p8 W/ c! b
代码展示) H# i. d- e3 e; F/ ?( w4 ^' z
* [( q6 S3 T# J3 ^( f* x
class Solution {
! b. n/ Y( K6 p! W$ r6 I+ u   public int minDeletion(int[] nums) {
& y2 p- E) ^& A9 Y6 [9 Y1 ^       int res = 0;
9 {8 h# B5 `( ~+ S       for (int i = 0; i < nums.length; ) { // i 应当和 i + 1 不同
, g2 Z+ t4 c( `; p8 |           if (i == nums.length - 1) {     // i 是最后一个,应当删除
5 o5 a' C: I! a               res++;: P5 ]- w0 A. a( [2 L$ w$ k- {
               break;
! Q0 y6 ?2 |9 t, h1 A# S          }! n$ g  A% R4 J  b
           if (nums[i] == nums[i + 1]) {   // i 和 i + 1 相同,应当删除,相当于 i++
; Y+ X& V* N/ u; W! @               i++;
3 K" ~7 O7 c8 w+ b/ c8 Y               res++;
- Q$ s# C6 r: M          } else {                        // i 和 i + 1 不同,可以保留,i += 2 以判断下一组5 J. H. W. r& C' ?% u
               i += 2;
- x0 G7 f+ {; V1 P& S          }5 H+ N& T0 ?$ G$ X
      }
2 |0 K) I) B* _. L+ \, q) i       return res;
' G3 r/ U9 U1 _3 z# d3 J4 u  }/ S; \5 p6 `- X4 P( a- N
}
6 H) w3 O( V/ `* I4 C" \
0 G- r2 p, y! e( N* K1 N0 e. ?8 N$ Y: \
【 NO.3 找到指定长度的回文数】
7 x- ^8 w3 H2 d, e" p* d5 c& G! C4 f- ^5 K: u& x8 v8 m% O  b, |
解题思路9 J7 i8 @- W/ R9 u, f9 g' K
举个例子:长度为 6 的第 k 大的回文数的前半边其实就是 100 + k - 1,由前半边复制出后半边即可。
9 E9 K8 r* n  B$ a' f; z; ]" W5 _1 x' P) c( q7 t" D
奇数长度的回文数在复制出后半边前去掉末尾数即可。; m" @$ e6 z0 N) \* {: J4 m

2 x  n, w" ^0 J0 N% @/ D" S2 |. o代码展示& M) m7 h+ S9 M

7 B! ?$ w. i. _5 \+ Z& Pclass Solution {
& r& }0 B3 s. ?$ H9 L   public long[] kthPalindrome(int[] queries, int intLength) {
( h7 t- f; n7 o) ~$ _! s       long[] res = new long[queries.length];  @0 y5 ]# p# [8 \* J2 J: E, b
       for (int i = 0; i < queries.length; i++) {" P$ m+ l2 Z+ U3 M$ \$ @7 ]
           res[i] = kthPalindrome(intLength, queries[i]);
0 r7 f1 h: N" _; ^( @9 W% |. Z! y1 J      }# j3 p# c  [, w% n
       return res;) A1 I: N, p# K3 A
  }; P. s% F% M7 r& q/ u  F
# s9 @8 l% H- ?; h, @
   // 返回长度为 intLength 的第 k 小的回文数5 ^8 Y/ S$ @- J- ]4 Z" [( `4 x0 O
   private long kthPalindrome(int intLength, int k) {! {0 ~5 H- s" i2 c! a
       // 处理偶数: t; x1 M$ n1 s( h" \& _/ m
       if (intLength % 2 == 0) {$ P6 }$ f8 v+ d. X1 A
           long half = pow10(intLength / 2 - 1) + k - 1;4 l2 k6 \+ u/ y' y' @: d& e' ?
           if (length(half) * 2 > intLength) {. v7 o# S. O0 M' r/ X% P
               return -1;
: a  S, v0 n% K( L4 N0 g% Q          }
; z- D1 a6 X# O; R5 g           long res = half;. G# t& P$ J8 D4 r  L+ M7 D( N
           while (half > 0) {
6 \( t' e  O6 [  M4 q! z  a               res = res * 10 + (half % 10);
7 m$ i% r. U2 W" ~6 u0 p               half /= 10;: Z& ^0 e% B- I& E- a. U7 [7 v
          }
# G; D% ~& Z& R- Y$ M, ^           return res;  T! o) |; b  q
      }
( {6 _; r* d$ L) _8 q1 \+ L1 p* y: @- Y6 l
       if (intLength == 1) {1 X0 L9 @5 H% |: |
           return k > 9 ? -1 : k;$ `. D2 n) M% ^  F9 U, z
      }
* c# _7 d& Q/ ?* D4 D2 Z
% @# }! R5 A% Y       // 处理奇数
+ U& ]- t' x/ Y$ j       long half = pow10(intLength / 2) + k - 1;* [6 s. {$ l9 t* h
       if (length(half) * 2 - 1 > intLength) {
; A% j5 f; o% _: ~           return -1;
) D: Z. a" X) B% C$ k6 l. i      }/ @. ]8 z" h; [$ U! r7 K  d
       long res = half;) V5 B( l1 h: g+ K5 s+ N  x
       half /= 10; // 去掉末尾数+ g7 U! ~* u) c1 ~( T5 t* B1 r
       while (half > 0) {1 c$ U' Y8 N0 J3 p: b
           res = res * 10 + (half % 10);# x& I# i8 Y6 h2 l
           half /= 10;* ^2 ~( y. p; L$ k( m3 f3 j& D
      }3 X* C5 F3 X0 h" P" i' O" e
       return res;
& j( i% ]/ m5 F; b7 E6 c+ Z" T  }9 n* \; O; k8 `$ H2 X
" Y/ P! ?8 K6 q% b+ b0 B
   private int length(long n) {
' h* W5 x' |6 P& b) s  Y- h       int res = 0;
6 @, x$ w9 U7 e5 U. S' e& V* L       while (n > 0) {$ z# `1 M5 t9 A# P* e! `6 I
           n /= 10;
) k, ~) T/ L' {4 q- S+ ]( u           res++;1 X" }* q& D* V/ ~6 v$ Z* O
      }# o0 [4 Q  P5 E0 C! E, [4 f; A
       return res;
! H: K; W" [1 }; u1 d+ g  C  }
0 |) j/ R8 Q4 k) W
9 h! |) ]7 q: S+ @9 P/ H5 |   private long pow10(int n) {  o! r$ r& O# [# k% ?2 j/ B
       long res = 1;* T- z/ D/ y8 _" V0 B
       for (int i = 0; i < n; i++) {
0 ~3 _0 ]2 {2 N) N: Y- P  s* k           res *= 10;
7 R4 q$ C: u) w      }
9 L9 L$ K6 Q' U. A$ e: D       return res;
& z. H6 u& X) _* _" N  }, l' H3 C$ |! X' c( f1 h, Z; o( f# [, H
}
) T7 Y: {  r# A% l
2 L+ U: N; f" P  }2 K# W8 _
- ]: d! v, b& a0 D4 j. O# n8 j【 NO.4 从栈中取出 K 个硬币的最大面值和】
/ c/ d5 r6 E! E- k. c% F) L) O1 F$ `0 \7 m+ N, @  E
解题思路. M2 J2 v$ x8 _" p
典型的动态规划问题。7 A( f5 F; y( c: b2 l8 ]2 L. V9 \
! _1 x& x4 G/ a2 {4 _# q. p
定义状态:dp[i][j] 表示前 i 个栈取 j 次得到的最大和。6 `$ a3 X7 l6 t' N; Q8 X0 e
' B/ i3 l: Z! M9 ]  }& ~9 ~
状态转移:在第 i 个栈取几个,即 dp[i][j] = max{dp[i-1][j-t] + sum(i, t)},其中 sum(i, t) 表示在第 i 个栈取 t 个硬币得到的和。
) o4 h! C7 T. d' ^/ {+ k. E1 [6 X# c/ v7 k* F* j2 T
代码展示$ G; y2 p- T; _7 H
% z: |8 }0 f  n9 `% M. O4 h, {
class Solution {, h$ S. S* l  E+ x3 W4 H! h
   public int maxValueOfCoins(List<List<Integer>> piles, int k) {
7 r$ z( W$ Y! p% r       int[][] dp = new int[1001][2001];- `. R2 U) y+ j+ N" B& l
       for (int j = 1; j <= k; j++) {
' P$ Q) ]0 M+ a3 Q6 ]& Z. g           for (int i = 1; i <= piles.size(); i++) {4 ~, z) m( i2 u1 z1 I* O- ?
               var p = piles.get(i - 1);
: f# m: A8 a( k/ ~. H# O* g' ~               int sum = 0;
8 }  y: P; V3 L) y& j               for (int t = 0; t <= j && t <= p.size(); t++) { // 枚举在 i 取 t 个$ C& V3 u1 S8 N# ]: ~
                   dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - t] + sum);
! y; [: a4 H% T" W                   if (t < p.size()) {/ w1 m& _  I( K& Z' z% t
                       sum += p.get(t);$ i  e( }# a) y8 e! g- I$ `  @  [
                  }
: [/ G) d8 l5 K# B+ ]0 ^( K; E' W# w' G' b
              }6 W1 W. }, g9 ]( S" ~- K( [6 q: M
          }
2 j4 D4 j/ {5 _( ?      }, Q" N7 X, D1 c( w
       return dp[piles.size()][k];4 O% f7 V6 x2 E1 [, G
  }
0 G+ ]8 r- Q6 {- X" f2 v$ U: X}6 d: i& H( v9 y3 a# o
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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