|
No.1判断矩阵经轮转后是否一致 解题思路 模拟矩阵的旋转即可。 代码展示 - class Solution {3 `1 y$ @1 [1 y E a( j( _: M/ B
- public boolean findRotation(int[][] mat, int[][] target) {4 ~6 p+ D' b4 P1 k) u* Z
- for (int i = 0; i < 4; i++) {! l. ?2 M; G, Z* o3 V- A
- if (equal(mat, target)) {
& d/ h& L8 q9 C& i, K' a; S9 _5 b - return true;
5 H( B# E) m0 N }3 U - }
( ?- s' M. j" G4 ?4 Q- w5 R# T2 B* X - mat = rotate(mat);: z) J2 @' G5 m3 e
- }6 U/ V% S2 x+ o) T/ h0 U
- return false; i! I$ H; ~4 J2 n: B, Z
- }
( w) Q; x) L L# l8 d' n( A- H - 6 Q V1 T7 J7 Q" _1 v; H# w
- private int[][] rotate(int[][] mat) {
; m; T+ x& ?8 W5 r8 G/ T3 q - int[][] r = new int[mat.length][mat[0].length]; O/ {' R- ?% U4 B
- for (int i = 0, y = 0; i < mat.length; i++, y++) {7 ?2 e& [: j r8 Q+ H+ A) I
- for (int j = 0, x = mat.length - 1; j < mat[0].length; j++, x--) {
# ?0 t y6 D2 m - r[i][j] = mat[x][y];
1 c" o4 Q" u/ Z# E - }4 J$ c( q" A% a+ V' A+ Q9 F! ?4 f. g
- }
$ M' P" C9 C5 H% a/ v - return r;
( \7 M5 t; ^' i/ c1 F8 q - }# v# c# w, X7 I7 h
+ m1 J) ]( r7 G- boolean equal(int[][] mat, int[][] target) {
. x5 l) I4 D0 r \ - for (int i = 0; i < mat.length; i++) {3 B2 B9 Q: }3 s1 L
- for (int j = 0; j < mat[0].length; j++) {
: x5 h& k6 c8 s+ B; q j0 _ - if (mat[i][j] != target[i][j]) {8 J5 ^+ |& \7 o2 ?
- return false;1 U0 K& Y( k: X) j" O
- }
# `: ]( p; ^- z5 [" n - }$ E* e J8 ^, v3 i
- }
$ m5 Z; s/ v' f. {% a; d - return true;$ e# {2 D1 t% r: M
- }
6 h% h& T6 r U* g - }
复制代码上岸算法公开课,毫无保留地将业界面试核心知识免费传授给大家,并配有课前课后习题以及标准答案集以方便大家学习。 长达近30小时的核心课程帮助大家掌握所有面试必备知识,在一个月内有效突破算法面试认知,从而有自信面对FAANG的挑战。 联系上岸小年糕,领取课件及视频 No.2 使数组元素相等的减少操作次数 解题思路 简单暴力地,从大到小依次处理每个元素即可。使用 TreeMap 的代码非常简洁,或者可以使用链表,速度更快。 代码展示 - class Solution {
/ d) L. W. [+ N* ]% _# k' ]$ { - public int reductionOperations(int[] nums) {, x, g9 m3 u1 A8 t, l8 k! i" {
- TreeMap<Integer, Integer> count = new TreeMap<>();" y1 z/ a& V& z" q4 Z3 f6 `2 f' Z1 j
- for (var num : nums) {
0 n3 A- T- d5 U+ H( R - count.put(num, count.getOrDefault(num, 0) + 1);
1 a8 T7 f3 ]$ V+ J2 b5 L9 L* N( b e - }
^* c) s) A) ^' n: N" i' P - int result = 0;
7 R0 A& z! i2 C8 h - while (count.size() > 1) {
. A# t8 @6 H% ]1 a- m; B9 ^ - var largest = count.pollLastEntry();, }+ |7 u5 Z( r$ S
- var nextLargest = count.lastEntry();& h# {! b# ?. i- J0 y" k4 W
- result += largest.getValue();
/ F4 P" m% M( `3 P" C$ W - count.put(nextLargest.getKey(), nextLargest.getValue() + largest.getValue());
' {3 d% @2 T1 I# X% f; i. E - }- Y) O k4 b9 x/ W! i7 R
- return result;
, I+ d4 C& g1 T: f! g - }
4 C, ^( t! F& S - }
复制代码No.3 使二进制字符串字符交替的最少反转次数 解题思路 枚举类型 1 操作执行的次数即可。 执行完类型 1 的操作之后,需要执行的类型 2 的操作次数是固定的。 我们只需要知道奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量就可以计算出类型 2 的操作次数。 每执行一次类型 1 的操作,奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量的变化都可以 O(1) 地计算出来。 代码展示 - class Solution {2 z4 U0 K3 r7 C- k6 f) Y
- public int minFlips(String s) {
( {5 J' `3 w! w" v. g9 U - char[] str = s.toCharArray();
- O7 w2 p! f, S- D! n3 R; [ - // count[0] 表示偶数下标上 0 和 1 的数量& a# \* L" e5 N4 d: t/ {( t
- // count[1] 表示奇数下标上 0 和 1 的数量
0 h, m v5 q t( {4 h- W- G/ U/ A5 @ - int[][] count = new int[2][2];0 E, t) c/ j2 _. u7 f
- for (int i = 0; i < str.length; i++) {& l5 D$ S4 q; z& P& C* i9 u
- count[i % 2][str[i] - '0']++;
' _5 }8 o" ?0 ~( y - }2 c' W' c5 \9 F1 m/ e7 X
- int result = Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]);$ ^" t) p) y% |2 u1 [1 t' f
- for (int i = 0; i < str.length - 1; i++) { C, ^0 z" e ^, K
- count[0][str[i] - '0']--;6 T/ _$ J+ I( s! v4 K) s6 m
- int tmp = count[1][0];
* b- s7 C4 G4 u2 N2 {; a" u3 k - count[1][0] = count[0][0];, g/ _1 V$ p9 j2 m: L
- count[0][0] = tmp;# E* m+ ~3 S. z' x% X
- tmp = count[1][1];% G' I) @+ ?) Z$ H
- count[1][1] = count[0][1];$ L* O4 h$ P; U% Z* ?8 ]1 O% t
- count[0][1] = tmp;2 ]! b; B) k. E7 ?: u6 w( B" X
- count[(str.length - 1) % 2][str[i] - '0']++;2 U, }. H9 {5 g+ d
- result = Math.min(result, Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]));) ~; o- Z# {) J
- }
' }' |9 l" M: O+ x9 ?( t9 z - return result;
) `# j- \7 V; s' N - }$ M- Z- `+ Q* @; Y$ R5 a
- }
复制代码No.4 装包裹的最小浪费空间 解题思路 二分查找。 对所有的包裹和供应商的盒子都排序,然后依次枚举每个供应商即可。 计算一个供应商的盒子的浪费空间时,从小到大使用每种盒子,每种盒子尽可能多装包裹即可,使用前缀和数组和二分查找可以快速计算结果。 代码展示 - class Solution {
0 m8 R& R. G+ B - public int minWastedSpace(int[] packages, int[][] boxes) {
/ O3 \2 ?6 j4 _8 s( V - Arrays.sort(packages);
# ~% i' s. p% N) D" e( w - long[] preSum = new long[packages.length]; ^. ]; c$ E& y% g
- preSum[0] = packages[0];
^( H. y0 X" G! ^8 |, s' S; Z - for (int i = 1; i < preSum.length; i++) {/ E1 R2 P( i, u0 P U+ q2 k
- preSum[i] = preSum[i - 1] + packages[i];- z0 ^4 R j% w8 y; Z2 o# N ]% R
- }4 L" b+ Q! Z& k! {
- long result = -1;
5 V) x p+ s# p' H' ^% k: G: W - for (int[] box : boxes) {; [$ }1 M" ]+ W1 h8 p
- Arrays.sort(box);6 F# k( ^& {2 o$ J0 l
- long t = waste(packages, preSum, box);
! b6 z7 C5 [* |- f9 o' ^ - if (t != -1 && (result == -1 || t < result)) {* x: {- m0 l7 S
- result = t;2 K1 S* t' r7 y, p1 B T9 T6 J
- }& ^- y* W/ E' w& I+ c, n( ]
- }6 `3 X% z1 }8 T' ^+ o: ]$ C
- return (int) (result % 1000000007L);
7 d. a. L& B3 z: r/ r9 u- }3 n - }
$ a' e5 z* s* j$ ? - ) X' H) P R2 Y0 }- X, V5 s6 H7 q1 M& q
- private long waste(int[] packages, long[] preSum, int[] boxes) {. c. a2 v0 n; V5 K
- int start = 0;
1 ?. E# O4 U- M% s- ~+ ^" X4 S - long result = 0;
- |0 e; e: ]6 z8 ` - for (int box : boxes) {1 A4 n/ |! T6 i% v
- if (box < packages[start]) {4 d% J9 T( A P4 q; P9 N- D- b
- continue;) G, P$ K! o/ i4 {) @ V
- }
9 W, U$ i$ i$ s' x - int index = binarySearch(packages, box);
" k/ e$ i8 w- k5 p( }/ K% }( l - // [start, index] 之间的包裹使用 box 装5 h$ L+ F! T2 i9 p- t5 F( x
- result += (long) box * (index - start + 1) - preSum[index];$ k9 X$ s, t% b
- if (start != 0) {
4 y2 I w7 J% k! H - result += preSum[start - 1];3 ~* g/ [3 ~( ]) f
- }
# Q4 |* @7 k1 }3 e; C+ `2 K' Z - start = index + 1;
4 \* ?) Y) U' V - if (start >= packages.length) {+ S+ [+ A( J! o" z) U
- return result;, F: R7 \* G0 z* ]8 _! b) }
- }
4 {( E% e+ ] a/ o2 e3 s3 L6 v - }
. }$ j4 m* o' I/ s! E% t) N2 r - return -1;2 j; i9 q4 V! Z1 A8 I4 D
- }4 c6 D7 G: _( B8 [
- $ F' P# \$ l5 s1 v6 i! k$ o% \
- private int binarySearch(int[] arr, int target) {. j1 a8 R( m$ Q( M- |. W6 m
- int l = 0, r = arr.length - 1;
( |2 t+ X% r( A8 A5 I- O7 c - while (l + 1 < r) {
( y+ @! V! {2 g - int mid = (l + r) / 2;
2 O9 J* [' U: `) z3 U - if (arr[mid] <= target) {
! R% i# ^+ B6 h; { - l = mid;3 a* k. r; d' |) Y) m4 I L
- } else {5 j& i/ |5 q8 B* O/ g' v5 W/ ]
- r = mid;
" V+ q g% G. {% `2 y8 j9 V - }
4 \, \- }( {5 W - }+ S$ l: O8 v; C, F+ O+ P
- return arr[r] <= target ? r : l;
2 M/ s* h' r* F6 M* J+ o" w) k - }- S/ u+ H" H* ~' b8 {) T3 X) ^' C
- }
复制代码 7 l9 f, O3 \9 e
( t0 D3 o: _2 y K# O) e
|