No.1判断矩阵经轮转后是否一致 解题思路 模拟矩阵的旋转即可。 代码展示 - class Solution {1 |4 _8 ~3 E8 s# Y
- public boolean findRotation(int[][] mat, int[][] target) {, a- { \& h9 }. ]7 C6 Z' z+ H
- for (int i = 0; i < 4; i++) {
4 m3 t& i% v3 i. v1 c - if (equal(mat, target)) {
3 C) F) l; ]& e/ s8 P- W - return true;
3 c3 O& B( Q. m# h: Z) A - }
Q, s2 x3 U. y0 k6 z$ Z - mat = rotate(mat);
! \) V; B& c4 P/ R9 o7 _) D8 ?) B+ l - }
|" V6 { a! f) S( {. }% ^2 [ b - return false;
( b# i# |6 x& S$ | - }' j0 C' s, T4 H' n
- 9 @1 u. G4 w9 g9 d; `' L0 I
- private int[][] rotate(int[][] mat) {
7 f0 G# p- P* V E5 z; |6 u - int[][] r = new int[mat.length][mat[0].length];9 p; C3 [: K7 N, m% @: @# Y0 p, T
- for (int i = 0, y = 0; i < mat.length; i++, y++) {
# w0 [: C# v! v! H4 b7 I, b4 u - for (int j = 0, x = mat.length - 1; j < mat[0].length; j++, x--) {
; \% E1 R# k" Z - r[i][j] = mat[x][y];5 F0 `6 E$ F' z
- }
( h; o! y, Z* f/ j, U7 R a) Q+ F, q - }
0 J) H1 x* s+ Q; b M1 V; r - return r;% ]- t- \, v- k. ?
- }
( \: A) S; `( M8 U1 I - % m# y( O9 }3 j, G' {$ d
- boolean equal(int[][] mat, int[][] target) {0 k% \* y" w! x- @8 {" b
- for (int i = 0; i < mat.length; i++) {* [: z* {4 Y+ ^/ a8 b! F7 R: J
- for (int j = 0; j < mat[0].length; j++) {, h: ~8 ?+ {- H0 ?
- if (mat[i][j] != target[i][j]) {6 P; d( g$ y0 U* a0 {' t
- return false; d! [/ l1 Y4 o6 m% J
- }
U! P( V k) N" K - }& E, D& P$ r- j# B
- }
( k$ v* G: X0 B3 L+ M, ]2 ?8 k8 } - return true;
) e4 x ~2 |2 k* P( z - }/ z4 S( v4 d7 G8 @; d4 M
- }
复制代码上岸算法公开课,毫无保留地将业界面试核心知识免费传授给大家,并配有课前课后习题以及标准答案集以方便大家学习。 长达近30小时的核心课程帮助大家掌握所有面试必备知识,在一个月内有效突破算法面试认知,从而有自信面对FAANG的挑战。 联系上岸小年糕,领取课件及视频 No.2 使数组元素相等的减少操作次数 解题思路 简单暴力地,从大到小依次处理每个元素即可。使用 TreeMap 的代码非常简洁,或者可以使用链表,速度更快。 代码展示 - class Solution {' O( @' ^( ~; w0 r1 N! K
- public int reductionOperations(int[] nums) {5 T, M9 ^! _" t) p6 V/ C
- TreeMap<Integer, Integer> count = new TreeMap<>();+ O( s7 L( }# G8 G1 _2 b& G& ]
- for (var num : nums) {
F3 z; n# v% z - count.put(num, count.getOrDefault(num, 0) + 1);+ X6 [% h' b9 A/ K
- }3 A3 d/ }1 I+ B* O
- int result = 0;
4 e3 i& r# ^6 ?/ y* N, o5 p - while (count.size() > 1) {: R; J! M Y/ d. _5 h! [
- var largest = count.pollLastEntry();. M1 `, ]8 v( C* T
- var nextLargest = count.lastEntry();
% W2 q1 h% R: V7 J5 Z% Z+ Y8 D7 i# y( R) g - result += largest.getValue();
) p0 m( ], a8 h4 [! O3 y - count.put(nextLargest.getKey(), nextLargest.getValue() + largest.getValue());
& g* \3 _/ t" h" K! [ q* z - }, m- p$ e, v& p- I5 [5 j) v+ ] p4 @
- return result;
" c- h, V3 ~4 H+ A2 m' \ - }$ ^# b0 g" l$ `% M1 o9 _
- }
复制代码No.3 使二进制字符串字符交替的最少反转次数 解题思路 枚举类型 1 操作执行的次数即可。 执行完类型 1 的操作之后,需要执行的类型 2 的操作次数是固定的。 我们只需要知道奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量就可以计算出类型 2 的操作次数。 每执行一次类型 1 的操作,奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量的变化都可以 O(1) 地计算出来。 代码展示 - class Solution {% d' m0 p5 L: t$ j1 A7 a
- public int minFlips(String s) {2 N" v/ F% x+ u* M8 l
- char[] str = s.toCharArray();
* c7 ~( K! S3 U0 w7 j: ^. J - // count[0] 表示偶数下标上 0 和 1 的数量- y, l/ s$ w' S$ P' \( k F1 U: m
- // count[1] 表示奇数下标上 0 和 1 的数量
% ~% B3 I* K" h4 G! D; o: J - int[][] count = new int[2][2];, @0 K) ~. {' i0 v( g' n8 l8 f2 E$ ^8 T& m
- for (int i = 0; i < str.length; i++) {
0 U* T1 B1 {8 X# O3 ~ - count[i % 2][str[i] - '0']++;. R3 V5 _5 r& u1 X
- }
# q7 {2 a! c! D+ ?( e. c - int result = Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]);
' U9 o( ^) g/ d* i0 c - for (int i = 0; i < str.length - 1; i++) {
# w9 z" N9 H- C2 f( c7 Q - count[0][str[i] - '0']--;) n# K, Y* `; r" B: i: S2 }, V
- int tmp = count[1][0];
: ^4 h7 h. O& V0 X0 n9 I - count[1][0] = count[0][0];+ L* n* V: s1 j9 U
- count[0][0] = tmp;8 E8 _6 s6 }# j1 _$ D- J/ _. y
- tmp = count[1][1];
! j, K/ ^, j6 @ - count[1][1] = count[0][1];# l" ?, ] }' ]0 X) G0 q
- count[0][1] = tmp;2 ~6 B& W4 N8 P0 r1 v# Y$ C
- count[(str.length - 1) % 2][str[i] - '0']++;
4 Q4 H8 g' i6 M) T$ @# s! d - result = Math.min(result, Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]));
- H' Y" _/ [* H7 \: j; N9 A - }
# g" l, k! W1 _9 x1 P/ D& x - return result;
# n v5 I1 E! I$ @& W - }" K/ Y* U+ d4 v6 y% E
- }
复制代码No.4 装包裹的最小浪费空间 解题思路 二分查找。 对所有的包裹和供应商的盒子都排序,然后依次枚举每个供应商即可。 计算一个供应商的盒子的浪费空间时,从小到大使用每种盒子,每种盒子尽可能多装包裹即可,使用前缀和数组和二分查找可以快速计算结果。 代码展示 - class Solution {
8 W% J! H2 l w0 Z - public int minWastedSpace(int[] packages, int[][] boxes) {: u3 Q- V: g/ C, S% a
- Arrays.sort(packages);4 i3 Q% a3 S) v5 x
- long[] preSum = new long[packages.length];
) p7 K) o, U2 V+ G% Q - preSum[0] = packages[0];7 V( M- Z3 v& o- n' H
- for (int i = 1; i < preSum.length; i++) {
0 Z. d r: a/ `# g - preSum[i] = preSum[i - 1] + packages[i];" ^* r9 v* v' k, j6 o
- }
, V/ m% t# {* Z1 O0 L4 n5 ] - long result = -1;" s* `% P/ G a* f" v( k9 w
- for (int[] box : boxes) {7 C- Z+ a5 b8 G6 u/ F. t
- Arrays.sort(box);
2 G7 P& q3 F5 y0 u8 e/ T, S- G' @4 O - long t = waste(packages, preSum, box);+ d# p+ y) @' x
- if (t != -1 && (result == -1 || t < result)) {
2 R& {- E5 c. h% c0 @ - result = t;7 L: l0 ]. V8 c% i8 @; j
- }
, W- u3 d( d, }& [ - }8 q) Y4 x3 E2 G s5 T2 c
- return (int) (result % 1000000007L);: o8 G1 D( H; }" [
- }
- G: U0 ]/ v2 j* g7 j - , J& n% R, {# V4 D" z3 H
- private long waste(int[] packages, long[] preSum, int[] boxes) {
% S! P$ G6 T9 P& N; H3 O6 V! H1 w - int start = 0;: n6 e H$ r+ j
- long result = 0;
* u, ?1 F! y0 w6 w- d% o1 q - for (int box : boxes) {, x5 f1 Q2 [; o
- if (box < packages[start]) {: Q6 Z7 j4 p2 R I. `
- continue;" k- t# r0 c' m
- }/ o" v) p0 _0 I
- int index = binarySearch(packages, box);# R5 j: D+ c4 ^ `. Y: z
- // [start, index] 之间的包裹使用 box 装+ k, h9 S9 W% ?' x' r0 `; Y- i, ?
- result += (long) box * (index - start + 1) - preSum[index];
$ `8 S4 q R( D1 a* U - if (start != 0) {
' B. p+ b3 _ T3 p' R+ V/ I8 i - result += preSum[start - 1];
+ E1 ~7 d4 l8 I- M - }' Z# m1 y$ b B4 E: L% W5 J. ~
- start = index + 1;* m r7 I9 C2 w) V
- if (start >= packages.length) {
9 E( U2 p' g& S, H - return result;2 S. } B& E9 f& P- h2 P2 C* Z+ ?; j
- }2 r- j8 e7 N: } y N
- }4 z4 ^: A! Q) _9 w
- return -1;
4 [6 b2 B* t$ h* k - }! ^) X, U' ~$ p6 Y: m
9 I3 C" J9 M) T- private int binarySearch(int[] arr, int target) {
1 I8 N2 |- ?9 E z: e - int l = 0, r = arr.length - 1;
+ Z+ T1 R! z( Z - while (l + 1 < r) {) i* G* H- z z, [ X: x) n2 @
- int mid = (l + r) / 2;# w) A$ l) f2 A( g1 e( l" f1 k
- if (arr[mid] <= target) {
8 N4 @. {( a' h; ?9 g - l = mid;2 j0 Z+ i7 S: C v. Q4 e
- } else {
% d/ n8 r- G) O% l, x - r = mid;
. q7 B# H5 R. P; Y( ^. H# X% ?& Q# P - }, k2 [. A( ]' u3 Y
- }4 b0 r3 ]+ l, l9 z* v
- return arr[r] <= target ? r : l;
+ C& i0 S8 P; m& d - }
, g) R- l1 `5 i2 g1 } - }
复制代码
' k7 J3 R L2 ^' N, h8 Z- |7 C& w0 S% M, ?
|