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

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

上岸算法 回复:0 | 查看:2959 | 发表于 2021-6-8 05:32:43 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

No.1判断矩阵经轮转后是否一致
解题思路
模拟矩阵的旋转即可。
代码展示
  1. class Solution {
    3 @4 Y* i. S, g. e. r# |
  2.     public boolean findRotation(int[][] mat, int[][] target) {% v* J& i# {9 G2 q5 `0 @$ Y
  3.         for (int i = 0; i < 4; i++) {- ?+ {( r4 s3 q, V  M% T3 R' p
  4.             if (equal(mat, target)) {/ M, S+ W8 I- [) a+ y
  5.                 return true;
    2 n5 a/ p; a; u7 m% ~& Y2 V. r
  6.             }1 f. {0 X. d- r% n5 W0 G0 S
  7.             mat = rotate(mat);
    6 x. w; O' S' h: C5 g) T
  8.         }
    9 x- ^1 t$ Q" S% ^- J, E% u
  9.         return false;
    # q3 j# H7 F1 M+ N7 u
  10.     }
    9 Y+ p% V, ^3 p" @; p

  11. . @2 M2 E: ~. U2 d
  12.     private int[][] rotate(int[][] mat) {7 [' `. }3 v! a* q9 q, |
  13.         int[][] r = new int[mat.length][mat[0].length];# C( h7 r1 k6 P; @
  14.         for (int i = 0, y = 0; i < mat.length; i++, y++) {: t$ c4 K3 @; T) m/ X; D% k: z: u
  15.             for (int j = 0, x = mat.length - 1; j < mat[0].length; j++, x--) {2 ^6 D- D" [$ g/ g5 `# c1 ~8 [& P
  16.                 r[i][j] = mat[x][y];2 A) l5 }1 u. b: ^" f! d
  17.             }/ J* y+ A( E' y6 {- m
  18.         }: W; O. e8 Y( d& r$ J
  19.         return r;
    + l" b6 n( y  }$ v& [6 Y
  20.     }5 D3 }1 \: s/ W) k5 w

  21. 9 j) c) T4 y: V8 \* a  ~
  22.     boolean equal(int[][] mat, int[][] target) {
    - t- p0 i" x# I2 F% Z  B
  23.         for (int i = 0; i < mat.length; i++) {
    5 N/ c. w2 |0 v% y2 @# a8 J
  24.             for (int j = 0; j < mat[0].length; j++) {0 i8 R) F1 Z' b6 R+ h+ e* j
  25.                 if (mat[i][j] != target[i][j]) {, d. |  [7 p6 Y. e/ f* h3 m* Y
  26.                     return false;9 {- Y4 d' J0 e- L( N/ l
  27.                 }
      H6 E3 Y  ?8 ]+ }* H
  28.             }- t6 w9 O6 f, N3 s0 v' n
  29.         }  W2 D/ `1 h. Y! D- K1 |
  30.         return true;
    5 I1 @, g& Z8 F3 i
  31.     }$ r; O' o/ p3 v4 A
  32. }
复制代码
上岸算法公开课,毫无保留地将业界面试核心知识免费传授给大家,并配有课前课后习题以及标准答案集以方便大家学习。
长达近30小时的核心课程帮助大家掌握所有面试必备知识,在一个月内有效突破算法面试认知,从而有自信面对FAANG的挑战。
  联系上岸小年糕,领取课件及视频
No.2 使数组元素相等的减少操作次数
解题思路
简单暴力地,从大到小依次处理每个元素即可。使用 TreeMap 的代码非常简洁,或者可以使用链表,速度更快。
代码展示
  1. class Solution {
    0 ]$ S0 C, |" _( v5 O
  2.     public int reductionOperations(int[] nums) {3 w6 d0 ~( `5 t7 A6 s6 V$ S+ a$ J
  3.         TreeMap<Integer, Integer> count = new TreeMap<>();7 h3 u/ o" K% V7 E+ O
  4.         for (var num : nums) {
    0 W5 I2 B4 U9 m. m6 H# s
  5.             count.put(num, count.getOrDefault(num, 0) + 1);
    5 p4 k, V( o, Y) k8 R- j* L
  6.         }
    . p- J8 U! D' {0 ?1 F
  7.         int result = 0;
      N5 D, o* A3 m( G
  8.         while (count.size() > 1) {& E1 i$ @9 y  K& W2 X+ V) a
  9.             var largest = count.pollLastEntry();1 x+ D5 p+ v* m' |2 P5 E
  10.             var nextLargest = count.lastEntry();
    8 T- q2 |% o; \; s$ I
  11.             result += largest.getValue();8 `/ D" p' E% c' z3 Q
  12.             count.put(nextLargest.getKey(), nextLargest.getValue() + largest.getValue());& q3 B9 K$ b; i: F! f$ Y( b& Z  D
  13.         }1 `' s: j- ]3 ?/ D* Q0 u% j
  14.         return result;1 o8 T4 C( N" M# A& r* |
  15.     }7 e6 |! K  {& P
  16. }
复制代码
No.3 使二进制字符串字符交替的最少反转次数
解题思路
枚举类型 1 操作执行的次数即可。
执行完类型 1 的操作之后,需要执行的类型 2 的操作次数是固定的。
我们只需要知道奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量就可以计算出类型 2 的操作次数。
每执行一次类型 1 的操作,奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量的变化都可以 O(1) 地计算出来。
代码展示
  1. class Solution {; H- u' z: q! y# H
  2.     public int minFlips(String s) {. L: Y" u4 j# T1 `0 v! |
  3.         char[] str = s.toCharArray();
    ( u; u5 `+ T+ I! l4 I! l" f  a/ R6 \$ y
  4.         // count[0] 表示偶数下标上 0 和 1 的数量
    ' R% y, n9 F- I; M# W0 s
  5.         // count[1] 表示奇数下标上 0 和 1 的数量5 k8 \8 x" F* j, }/ e+ |* y
  6.         int[][] count = new int[2][2];5 L0 W  e. h! N% o# }
  7.         for (int i = 0; i < str.length; i++) {
    " M6 y; j% l* d6 A3 K, j0 \
  8.             count[i % 2][str[i] - '0']++;  V$ {6 F5 M* `1 _8 t* m0 v
  9.         }
    0 k  j" g6 H" y" M' c
  10.         int result = Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]);; c: ^5 k$ A6 o7 `  N) b: {
  11.         for (int i = 0; i < str.length - 1; i++) {
    1 c. r6 L: M% |6 J: x9 @+ u
  12.             count[0][str[i] - '0']--;9 ?' `: V8 m+ G, _. T( _
  13.             int tmp = count[1][0];0 R- Z; Z# [- M9 {
  14.             count[1][0] = count[0][0];
    : E; C$ G' a- g6 E
  15.             count[0][0] = tmp;
    , M+ q; l$ X: C2 J
  16.             tmp = count[1][1];
    $ n) `4 `- V0 o
  17.             count[1][1] = count[0][1];5 ~" X8 `7 b9 E' ~
  18.             count[0][1] = tmp;
    1 [! i  s2 j+ h8 a, p$ i9 L
  19.             count[(str.length - 1) % 2][str[i] - '0']++;8 D: _0 u# J% G& N6 h# Z
  20.             result = Math.min(result, Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]));- z3 \' R$ X. f9 U( ]& O
  21.         }& Z, Q! L0 B4 R' ^
  22.         return result;
    9 ]0 ]. m  x5 Y+ ]" j
  23.     }7 i3 a7 U4 P% ?. L, C3 z! P' F
  24. }
复制代码
No.4 装包裹的最小浪费空间
解题思路
二分查找。
对所有的包裹和供应商的盒子都排序,然后依次枚举每个供应商即可。
计算一个供应商的盒子的浪费空间时,从小到大使用每种盒子,每种盒子尽可能多装包裹即可,使用前缀和数组和二分查找可以快速计算结果。
代码展示
  1. class Solution {% R! @; V: g/ G0 N; ?3 Z+ G
  2.     public int minWastedSpace(int[] packages, int[][] boxes) {& A' P4 l/ F% n% K
  3.         Arrays.sort(packages);' O! s% q; X* c# r: P* B
  4.         long[] preSum = new long[packages.length];% d! e1 O0 u+ V5 S, {! |
  5.         preSum[0] = packages[0];6 Q* I# H; V* O6 W, A
  6.         for (int i = 1; i < preSum.length; i++) {
    6 r$ `& V- G4 o! u( D# p  m9 z
  7.             preSum[i] = preSum[i - 1] + packages[i];& A% `1 s3 d( D7 y% S/ H. @
  8.         }8 j5 N% \" s# @2 M
  9.         long result = -1;
    ! e5 A, i7 d' H  F% N/ r
  10.         for (int[] box : boxes) {
    7 S! x8 ^, Q  ^& [  t
  11.             Arrays.sort(box);
    ; h6 h/ e  t8 m6 y7 @
  12.             long t = waste(packages, preSum, box);
    % O* ^- }" i& g4 N2 H8 _( K' b
  13.             if (t != -1 && (result == -1 || t < result)) {
    0 i9 U: {6 P( Y4 E
  14.                 result = t;
    % w7 R  ]( ?$ U" k: n' C
  15.             }; H% H" k+ K% @+ S; T2 x
  16.         }& A6 \6 G. ~5 O! o! h
  17.         return (int) (result % 1000000007L);0 y5 f2 ^  h- s) U% U) R! c
  18.     }& e& [) ^* q& x9 \6 D
  19. : R6 ]. P- c! b7 A
  20.     private long waste(int[] packages, long[] preSum, int[] boxes) {! n3 x: r, P# l% v9 L/ d4 ^
  21.         int start = 0;7 z+ R* v8 ]2 H, N
  22.         long result = 0;1 |0 w; k1 k5 E$ K, i* y
  23.         for (int box : boxes) {
    0 `3 ]! k, w! s2 T
  24.             if (box < packages[start]) {0 [# R! q) Z6 f3 T) ?9 i
  25.                 continue;7 D  A% O( j  @2 |+ c
  26.             }
    & O6 v& U# f" [+ F$ G4 w0 ~
  27.             int index = binarySearch(packages, box);/ O2 b6 Y; V0 F( G; h2 f
  28.             // [start, index] 之间的包裹使用 box 装
    : t2 M/ |) Y9 \7 C  t2 [) v
  29.             result += (long) box * (index - start + 1) - preSum[index];
    % u/ T# }$ C3 V) I4 l
  30.             if (start != 0) {
    2 ^7 M. x) g1 e. N
  31.                 result += preSum[start - 1];9 |  X. b3 i# Q, S5 M) o. d
  32.             }
    ; {6 i5 \# ~) D$ X- `
  33.             start = index + 1;" J) A: V5 a5 z- B+ ~
  34.             if (start >= packages.length) {
    ; u8 @, w: m& A' S0 \2 W/ S: y6 n
  35.                 return result;6 k; L8 F9 ^3 m
  36.             }
    : ~" M4 ~1 ^: ?! ?* A, X9 @
  37.         }
    ; N- n& N0 Y: S/ r1 T
  38.         return -1;
    ! u  a- q, g- h% q# _
  39.     }
    2 b/ @: d, ~- V$ k$ |

  40. & C' r. O( f) X7 i6 f
  41.     private int binarySearch(int[] arr, int target) {
    $ E5 y& ?9 y4 l7 A% O% M$ [! b
  42.         int l = 0, r = arr.length - 1;
    + }# L6 W2 ?! d8 r* h, W. U
  43.         while (l + 1 < r) {; U3 P! r/ ~& X# \
  44.             int mid = (l + r) / 2;
    . f4 K5 @' B0 o5 U1 j$ B- P
  45.             if (arr[mid] <= target) {
    * ~  f+ V$ t' A
  46.                 l = mid;$ q! V* j- |% S6 g+ K
  47.             } else {6 ~5 T$ j1 e2 F
  48.                 r = mid;' q& [6 T$ t, C; r  p4 [
  49.             }/ Z' Y9 ^+ H/ |* }2 b  W- J
  50.         }
    , t+ c" O- M, }% @" L8 N
  51.         return arr[r] <= target ? r : l;
    9 z8 L1 h. T6 i: i
  52.     }
    2 L/ }6 N6 d1 r
  53. }
复制代码

% ~. {, ^2 Q1 R9 ~( |! D  ?
9 P  b: P( G7 i

本帖子中包含更多资源

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

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

本版积分规则

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