|
No.1判断矩阵经轮转后是否一致 解题思路 模拟矩阵的旋转即可。 代码展示 - class Solution {
) D% \. a& {. s/ f) a6 S - public boolean findRotation(int[][] mat, int[][] target) {0 g5 m9 D% H8 d( D$ G
- for (int i = 0; i < 4; i++) {
( `( B( ?; N# x - if (equal(mat, target)) {
& S2 i6 o4 S$ G6 v# g - return true;
. x5 ?; c' M7 M3 M6 X: D5 ~ - }$ O8 i6 T9 V2 f- u! S$ E9 J0 P& x. H2 b
- mat = rotate(mat);
' b6 e# U& T* l - }7 [1 s+ |# d: }, d' f
- return false;# G. [# u' Z ]( s$ H/ d0 l
- }
; L7 s, \7 n! R - ( G L, V; i1 x# {
- private int[][] rotate(int[][] mat) {
- @ I* M) ]" o* T, `4 J - int[][] r = new int[mat.length][mat[0].length];
5 Q# W4 d S |, X - for (int i = 0, y = 0; i < mat.length; i++, y++) {2 h+ Y$ M8 u$ [" M; [
- for (int j = 0, x = mat.length - 1; j < mat[0].length; j++, x--) {
1 d# s/ R, Q5 X$ Z2 Z! t: V - r[i][j] = mat[x][y];
; \% B( v& A3 \% l4 r8 K - }5 x, i* D% W+ ?! H2 Z7 i; _
- }$ @ Z8 G/ T8 v3 |; C2 ~- d; c
- return r;
5 N1 ] F( l( t4 {1 C# v% B - }. C3 f: f- g* P/ e" R
+ O% F8 G7 S! z- boolean equal(int[][] mat, int[][] target) {/ C/ ]0 L, q9 k% v! ^5 x& R5 d
- for (int i = 0; i < mat.length; i++) {5 H4 h5 P9 O* G! q, f5 n
- for (int j = 0; j < mat[0].length; j++) {
: L. `5 _3 p& k# i, K& J- e J7 K# O - if (mat[i][j] != target[i][j]) {! ?& P" b. c2 P7 D6 L2 I- g
- return false;8 N# F+ h2 A8 F
- }6 I8 S0 E+ h4 l p" v
- }
0 f0 Y' ^! A* R6 ?" H5 v - }
6 u8 o2 B- \- m4 j. C - return true;% m2 w+ w8 ?7 J5 [. V" u" ?
- }
0 _0 u9 \: K5 \! J - }
复制代码上岸算法公开课,毫无保留地将业界面试核心知识免费传授给大家,并配有课前课后习题以及标准答案集以方便大家学习。 长达近30小时的核心课程帮助大家掌握所有面试必备知识,在一个月内有效突破算法面试认知,从而有自信面对FAANG的挑战。 联系上岸小年糕,领取课件及视频 No.2 使数组元素相等的减少操作次数 解题思路 简单暴力地,从大到小依次处理每个元素即可。使用 TreeMap 的代码非常简洁,或者可以使用链表,速度更快。 代码展示 - class Solution {
! w2 ^- s0 I, N" r - public int reductionOperations(int[] nums) {
1 i/ M% i& {$ G5 T: V0 ` - TreeMap<Integer, Integer> count = new TreeMap<>();
3 M! D( G; M# i! k% `7 x. O$ W - for (var num : nums) {
/ K8 A( F C l+ E2 j - count.put(num, count.getOrDefault(num, 0) + 1);
9 s+ S l$ R: @6 f! f% K0 R8 m" e - }
: O# x( P1 o( V; `; i- Y" @6 X1 Z - int result = 0;
' F7 v' i# i+ B - while (count.size() > 1) {" Z- P5 J/ o: h( T1 Q
- var largest = count.pollLastEntry();. }1 {$ Q- G: _: R) N/ _0 ~. S
- var nextLargest = count.lastEntry();4 e# ~& L- d- C% q
- result += largest.getValue();6 C! u, c7 v" v6 v3 v6 {
- count.put(nextLargest.getKey(), nextLargest.getValue() + largest.getValue());) Q4 \9 o2 u3 `1 ?0 m3 ~
- }
# q8 _& W. ]6 f0 Z2 G& R* N" Y9 k - return result;
( y' y/ z1 B4 }% I: c3 c5 r3 t2 {2 Q - }
) V) u8 D \) `8 D - }
复制代码No.3 使二进制字符串字符交替的最少反转次数 解题思路 枚举类型 1 操作执行的次数即可。 执行完类型 1 的操作之后,需要执行的类型 2 的操作次数是固定的。 我们只需要知道奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量就可以计算出类型 2 的操作次数。 每执行一次类型 1 的操作,奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量的变化都可以 O(1) 地计算出来。 代码展示 - class Solution {
; H( O5 j- {+ v8 A$ E$ ` - public int minFlips(String s) {
5 ~& X6 b( y ~2 p! Z4 f( \1 E- } - char[] str = s.toCharArray();: N7 |/ e* T8 d/ R* i7 f' V6 A
- // count[0] 表示偶数下标上 0 和 1 的数量1 ^$ t$ t, ~* o# l$ _! ^ W
- // count[1] 表示奇数下标上 0 和 1 的数量- x$ {" i5 }' h6 W5 x1 U& }
- int[][] count = new int[2][2];$ F S% `1 ^3 F
- for (int i = 0; i < str.length; i++) {
4 G7 @! L* d) L# A; P- _* z/ x# {( h - count[i % 2][str[i] - '0']++;2 U8 c1 s2 g" q, c5 x
- }
9 Y9 I: S9 C% m4 X% U4 ] - int result = Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]);( Z' y$ c W+ @9 n9 P
- for (int i = 0; i < str.length - 1; i++) {) e% R4 }* `$ [2 G) ]
- count[0][str[i] - '0']--;' h; z. `! g9 Q0 {+ l3 M1 r
- int tmp = count[1][0];
% g+ Q1 p8 W* o; b% v - count[1][0] = count[0][0];
. X5 i; g; |# U - count[0][0] = tmp;: ]% o% E" N8 E" U9 o0 |, ?
- tmp = count[1][1];
$ J6 [1 A: D5 R+ W4 s/ \ y) @ - count[1][1] = count[0][1];
7 d: M& J) U+ ~- S, f- e - count[0][1] = tmp;- d/ |+ g3 @/ J3 G
- count[(str.length - 1) % 2][str[i] - '0']++;' z8 ~4 Z7 u& O, l+ Y
- result = Math.min(result, Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]));; Y3 ~/ a' z, X* V2 O; d. L
- }7 t( h; V1 F( H w8 }0 M* V5 T
- return result;4 ^& g. Z; a) R3 f" U
- }$ p5 E6 F" j2 s: a3 x$ j
- }
复制代码No.4 装包裹的最小浪费空间 解题思路 二分查找。 对所有的包裹和供应商的盒子都排序,然后依次枚举每个供应商即可。 计算一个供应商的盒子的浪费空间时,从小到大使用每种盒子,每种盒子尽可能多装包裹即可,使用前缀和数组和二分查找可以快速计算结果。 代码展示 - class Solution {
' n" K9 t% F% n' _0 v* q+ k - public int minWastedSpace(int[] packages, int[][] boxes) {
. _+ N4 A/ l7 d - Arrays.sort(packages);
7 C& U! ?7 v1 K/ w$ p! z - long[] preSum = new long[packages.length];4 t/ k7 X7 K" w6 k
- preSum[0] = packages[0];
4 {" m& [4 H1 `$ V9 P - for (int i = 1; i < preSum.length; i++) {$ [% G" V m7 ^& s+ z! u) m) G
- preSum[i] = preSum[i - 1] + packages[i];
1 b# L1 |2 Y( K - }
2 r: L4 v9 d7 p( G# O* P+ p6 P - long result = -1;/ c. Q4 V! F2 P, g# k% e* H7 M5 N* v
- for (int[] box : boxes) {+ b2 i( G* n8 u% h/ C
- Arrays.sort(box);6 S$ X" w; B0 J( W7 L; m: x* y! \. I
- long t = waste(packages, preSum, box);0 ?3 G% H$ t+ _% r( Y2 p2 K6 A
- if (t != -1 && (result == -1 || t < result)) {- \* A$ l+ X/ l4 @, @
- result = t;3 S1 ?+ {; Z, X8 u
- }5 `- W7 s/ l) `& z6 u* q& h
- }
1 L6 r. U% w! Z% K V1 D/ K - return (int) (result % 1000000007L);
) J0 j) i3 r* }4 O2 k - }
4 C. g/ k/ i$ P - " C8 O3 b( |9 B* d! Y2 ~3 b6 x+ ?3 c
- private long waste(int[] packages, long[] preSum, int[] boxes) {; q2 |0 v8 E+ R% U- N; F
- int start = 0;
7 r; n$ J6 }, `6 l: b& R) R - long result = 0;
/ Z2 x: ?4 D$ J: F - for (int box : boxes) {
' O$ n( D$ V5 O9 j+ ^- C - if (box < packages[start]) {6 [1 q: s6 B/ s0 Z$ M: Y
- continue;
- u; x! [0 h9 X! P2 B% `1 r% f* X - }( h$ m& T& @. l" N2 ^
- int index = binarySearch(packages, box);
* i9 D: m( C! }$ I1 m - // [start, index] 之间的包裹使用 box 装
& s5 {1 l( P. ]( R: w% [3 _) A - result += (long) box * (index - start + 1) - preSum[index];
( [; @9 m9 c% m7 ~/ c4 V/ b% S$ J/ f - if (start != 0) {
* N! w# X. w# G* Z( R5 g, T - result += preSum[start - 1];6 A. u; h. g( _4 c8 O
- }
P4 G z, K0 V" t) U, h/ x - start = index + 1;* m4 k9 U$ U8 y% p* E& ~
- if (start >= packages.length) {0 v1 Z+ R4 P4 F, Q; X7 F
- return result;/ Q# E1 N* a; }
- }. d, e9 M' N* P# s2 w( d3 S. |
- }# P x6 l' ]; R4 Q
- return -1;
2 p/ @ R3 V+ k1 Y - }
2 r+ Y$ A/ ]5 c - % m# t" F6 }; F! M
- private int binarySearch(int[] arr, int target) {
" W' ?" |7 G# q; f" o5 f: Y7 U& V8 O! C - int l = 0, r = arr.length - 1;; h _* {: F' [
- while (l + 1 < r) {: s, v' ]. d+ G: F0 r$ [9 b6 {; a# i
- int mid = (l + r) / 2;0 {. p( z( H: o$ W3 p$ N
- if (arr[mid] <= target) {
8 D) @+ A' ~ ?+ d" y, T- H - l = mid;
$ h% @1 v/ Z E. c! b# } I - } else {
I4 Z( r* ^! ?7 A# E - r = mid;1 v7 X i) X: x8 R8 K$ r0 G
- }
" J/ v6 N% q1 ?$ _ - }
$ F- r/ ~0 I1 a# b0 F0 V - return arr[r] <= target ? r : l;
7 i6 h3 G# `: y# T - }
4 Z1 L/ H& F: o+ K* V - }
复制代码
# C$ {! M8 E1 I. J5 n" C. S% F8 x3 w6 w7 \
|