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