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

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

上岸算法 回复:0 | 查看:3175 | 发表于 2021-12-26 20:14:55 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
【 NO.1 反转两次的数字】
1 a( u& ^  V$ G- G7 R
0 }2 A+ Z: i+ P( S. I$ k5 e1 E解题思路
0 F) ?7 k3 H5 W) P1 B通过不断 %10 取最后一位即可反转数字。. M; h5 _& h; t: }' ?6 e
+ a1 t! i. z2 Q, w* K
代码展示
5 v5 {# i, Q/ t3 k5 w
$ D+ i$ \1 V4 N, L- cclass Solution {; Y9 I+ d8 |  a
   public boolean isSameAfterReversals(int num) {/ W" s! h/ o( m: o2 `
       return reverse(reverse(num)) == num;
2 U2 Q- ^7 `# M9 K$ B  }
4 o0 T3 I- {4 R% S+ b$ v
7 n- {  L& Z5 L* [   int reverse(int num) {
4 o5 s" y" R: n2 a       int ret = 0;, O4 k7 ~5 f( N8 I  c7 D, S) B
       for (; num > 0; num /= 10) {
' d7 e% T! @% L  i  p* V: R           ret = ret * 10 + (num % 10);, \$ Q) v# j9 l- x" @, ^
      }
5 y& S  d: h( |' ]7 r6 d       return ret;! o! I# @4 j9 `1 n
  }0 a- n/ _! P- s4 @  ]5 d
}
0 o8 `! V, h; z$ F/ N* q$ P, W9 H3 \
, |1 r) c# z0 R2 h6 h
【 NO.2 执行所有后缀指令】4 f# ~! P8 G( f  w- V5 N7 q

! p" B1 z5 Q! R& k- d# q解题思路, K. ^/ [8 p2 Q# @
模拟执行即可。
1 c& S  ?2 z8 A0 W
) }% x" g; N* I4 @, T% W! t- a) S代码展示; L( _' O& z; u1 Z8 P
4 w7 m1 x; {. y7 I. ~' P
class Solution {- `% s1 Z* A0 I) l1 A, u; {6 t- _
   int[] dx, dy;* h6 |7 w7 x( ~' R8 y. D
5 a4 X0 e6 _3 E$ v9 S  ?/ V" A
   public int[] executeInstructions(int n, int[] startPos, String s) {8 b6 B. T9 t8 h6 G/ F2 u
       dx = new int[256];
8 X5 X5 K# c" C9 W       dy = new int[256];
6 h# L+ P3 k/ m' R9 m8 G1 K. C       dy['L'] = -1;0 m( R* h# I% h1 {) M' e% y- r
       dy['R'] = 1;7 I4 M8 E* M: F! H7 v. \  @! ]
       dx['U'] = -1;
/ u4 {, D; {/ \( ~8 F( i       dx['D'] = 1;4 S9 w. g+ X  z: R* ~7 Y4 w
       int[] result = new int[s.length()];* x2 j7 l+ X8 m9 f6 G1 E! Q2 g
       for (int i = 0; i < s.length(); i++) {
7 `1 e/ q; X' p& G, P( G0 A9 ?! Q           result[i] = execute(n, startPos, s.substring(i));5 x" H) c7 i5 z$ s
      }
3 r7 r0 H2 U) N       return result;: s+ y. w  \2 V, t$ I
  }
0 H4 H; r# M  i$ b- s; K( f$ I% _! m( W+ l1 q8 `; p
   int execute(int n, int[] startPos, String s) {
# D" w5 ~( P7 i, Y8 D5 M. F       int x = startPos[0], y = startPos[1];
" ^+ \& _9 k1 y* ~9 J3 S0 Q       for (int i = 0; i < s.length(); i++) {7 a8 U, V# B3 T8 i  o
           char c = s.charAt(i);! l$ n6 D! d% e% M
           x += dx[c];7 {! o9 E! N* H0 U' B
           y += dy[c];) p5 g7 B: U) e% h
           if (x < 0 || x >= n || y < 0 || y >= n) {
: p! g$ K" n5 ~               return i;
, E6 X; @; V$ a. q# v) c. S          }
+ D0 u9 D) |2 e3 A) f+ `2 R4 o      }
  B: W: f& o$ Y0 P$ @2 b4 E       return s.length();
% y! p& K9 v( B5 ?# w  }
. u* p" R+ n* @1 {4 D( n}
' L: S6 w1 Y" n6 n* _1 I$ r) i% N. S) I0 V/ P# U& S- C2 `

0 ~2 f$ H4 e$ x* k2 _! U0 c& o【 NO.3 相同元素的间隔之和】
- Q$ ]" b7 n9 b8 v# U- B6 e, W5 `+ ], ~6 U8 V: t: d
解题思路  g; b7 e  m6 d( g: J( N8 N
记录每种值出现的所有位置,将这些位置排序,然后求出前缀和。
* f1 V0 o* u7 W' ^1 b. _9 v( k& Z/ f# f2 O6 Y8 m
利用前缀和快速计算间隔之和。
& N! g2 _2 G  h5 f. q, R5 e2 W+ v: d* G" p
代码展示
# ~6 A/ j) k1 ^, s0 ]. w9 E, g# p+ l( I
class Solution {5 D* I% ?  Y4 Q5 E6 l* E2 p2 H" {
   public long[] getDistances(int[] arr) {
( T1 w% A* s+ [4 k% Y; K       Map<Integer, List<Long>> positions = new HashMap<>();! P* L3 m- T$ Q
       for (int i = 0; i < arr.length; i++) {
. w" `& O' w9 [! e           if (!positions.containsKey(arr[i])) {
. n( p$ {# c- _               positions.put(arr[i], new ArrayList<>());* m8 g! {" M+ M$ r1 c) f9 X
          }
5 e  W- r( i0 E/ Y8 x           positions.get(arr[i]).add((long) i);6 m4 E9 e5 M( `! R. ^
      }: u6 V5 Y: q2 {6 o: I
       Map<Integer, List<Long>> posPreSum = new HashMap<>();9 y: ^- y4 G! U% q; V! O
       for (var e : positions.entrySet()) {
  j, F% Z! N. C3 [( ~% {           var pos = e.getValue();# F! `! a# A1 i8 y% W
           Collections.sort(pos);
# t5 D5 @% J- ?9 Y. H           List<Long> preSum = new ArrayList<>();
" ?, i( G  L7 y9 q           preSum.add(pos.get(0));
0 {0 T5 j% y& W4 w, U" w/ W7 o           for (int i = 1; i < pos.size(); i++) {7 w" i/ h" T4 C2 o1 e* H
               preSum.add(preSum.get(i - 1) + pos.get(i));
1 Y9 _4 }' q; Q          }
0 s4 A- i) z7 `( c% F           posPreSum.put(e.getKey(), preSum);
1 S! W: `& L6 m      }
# E) u" F( Y$ P1 _" L% ~! j3 I( h5 S: M: V0 ~# Q

6 M2 ^* M3 W* |- {       long[] result = new long[arr.length];8 c/ r1 m, ?& n) |! v# v5 k2 W' ]
       for (int i = 0; i < arr.length; i++) {
) l4 }9 V2 m* d- o% V           List<Long> pos = positions.get(arr[i]);( T! z9 U# P( m& o
           List<Long> preSum = posPreSum.get(arr[i]);
4 [/ n3 s, ?- C! S. {           long n = preSum.size();
# @4 J7 R# w* E# o, h7 t           long p = bSearch(pos, i);7 ~4 v3 e) v0 e
           long left = 0, right = 0;
9 {7 d3 }& V; ?4 o: ]" v# B           if (p > 0) {
7 E9 A1 c3 w/ m; S               left = p * i - preSum.get((int) (p - 1));2 x  G/ a7 H: x  S6 c
          }
8 T. x5 ?" C# y% c# K           if (p < n - 1) {; d  Y" R0 O% r' k3 \# o3 t8 Z7 i+ V
               right = preSum.get(preSum.size() - 1) - preSum.get((int) p) - (preSum.size() - p - 1) * i;
* j) T( K. ]. X  A* P- E3 x          }
+ r/ Y* r: R8 J           result[i] = left + right;1 M& c9 d$ u9 c; \! `% z
      }3 {5 `1 q7 y; h: x
       return result;+ ?( W! b. h  Q5 C
  }
8 Q/ e; ^/ H1 O$ p  {" C' w- q( Z  M0 f  r
   long bSearch(List<Long> list, long target) {
/ f$ i+ U  W  T       int l = 0, r = list.size() - 1;( Z4 _+ J2 I+ M- X8 C
       while (l + 1 < r) {
3 q/ v: I# ~% U: e           int mid = (l + r) / 2;: J1 y( K# _, g9 f; G, C5 [* ]
           if (list.get(mid) == target) {
& _; v# d- |5 N+ Y! z2 v               return mid;
) [' G; I5 C+ |9 e4 R8 x5 Z          }
2 N6 ]. ^( a* O( i' n3 s1 U           if (list.get(mid) < target) {; v3 W, ]/ [4 W; ]" U
               l = mid;! Q7 A, r, ?8 X) u( h/ b+ |0 z  M
          } else {
+ Q2 K8 F) h4 Y' ]               r = mid;
; _0 D5 N2 |) s2 b, i4 S$ r          }
. Z- K; H# U& }0 a4 i  g5 b      }5 h* H' b2 S+ G' `
       return list.get(l) == target ? l : r;
3 v5 O# e: W5 M) _. _8 O  }. l/ w7 U8 D$ A4 a/ p6 w0 K& C
}
) A# O+ i! n4 c! z( T. S' \- |6 \: @/ F; ]9 s9 v. [$ X

% ]0 Z( \  y# T+ l( M" M$ N【 NO.4 还原原数组】
. K+ h' A' h0 P$ s2 s) w
- P" w1 A! c, A解题思路
% ]' B( e. h, Q' l$ J首先要找到 k,枚举 nums 两两差值,统计每种差出现了多少次,若出现次数少于 nums.length / 2 那么这个差值一定不是 k。
& y) q' u* C7 }" a3 _2 X2 m& A2 D2 U
) u+ Y9 _* e' ]) P( |6 Q8 ?然后对于每种出现次数不少于 nums.length / 2 的差值,把它当作 k 尝试还原数组。1 p% s  s0 n* v3 `$ k
% `- f8 E6 v. k( ~1 R; x
代码展示4 ]5 B$ f/ ]+ m- ?2 P- ^* ?  y  ^
8 \# ~7 [; L3 F' u
class Solution {
* ^4 m/ h' N' R7 ?7 K- t. \   public int[] recoverArray(int[] nums) {3 ~6 W1 b" z  L$ ~& z
       Arrays.sort(nums);
+ F6 B5 _$ M  F& z: V       Map<Integer, Integer> count = new HashMap<>();; w/ W1 n! |! j2 k# }" S
       for (int i = 0; i < nums.length; i++) {* J# [! a- v4 K) ]7 }  w
           for (int j = i + 1; j < nums.length; j++) {$ C7 s; d  c7 `
               if (nums[i] != nums[j]) {
& E" |5 d1 I, |) P                   int diff = Math.abs(nums[i] - nums[j]);/ `' S% b# ]% D/ J! o
                   count.put(diff, count.getOrDefault(diff, 0) + 1);
) ]% e% _6 d+ j              }
& z; D8 Z; ^$ P: `! m          }+ ^. A! u( i+ y8 g7 k( [( p5 s
      }9 @8 G. ^9 ^% {
       for (var e : count.entrySet()) {
/ B$ \3 [0 o  ?6 c, h           if (e.getValue() * 2 < nums.length) {
8 c0 c1 w2 \! ^" P7 v8 f- F               continue;; I% C% ?+ F  n' @( r4 |
          }
" x1 Z# g5 q: K  L1 z1 W  S. J7 r           int[] result = recoverArray(nums, e.getKey() / 2);
7 y/ J! g7 ?- M7 u           if (result != null && result.length == nums.length / 2) {
+ r+ h2 \# h+ K1 H               return result;
3 C' c4 n( ~* \& X, X9 j4 i9 j7 ]          }8 R" B3 o, E. b! K- `
      }/ V$ e7 i' t) s) L8 ~# a; O
       return null;
: w* Q/ F2 x; D+ V* G- B  }2 |- z* I% y9 J9 X, c8 j

# Y0 }3 J7 e' \: _' H& e: u5 c   private int[] recoverArray(int[] nums, int k) {
% G0 X4 k, Z" H       boolean[] found = new boolean[nums.length];* W3 i2 _. \0 X& N/ w
       List<Integer> result = new ArrayList<>();
* {4 U+ J$ x7 U  I0 h+ ^. z) Z; s9 I       for (int i = 0; i < nums.length; i++) {
3 N  D# E8 O2 s; z" @$ ?3 i           if (found[i]) {0 [) Y8 d( B* f5 r: X6 c
               continue;
; ^6 [  }6 ?: L7 h' i          }0 L. V# Q- z% Y$ o
           int lower = nums[i];; ]* U& i/ T9 T0 N2 z+ I# }
           int higher = lower + k * 2;
1 j+ t7 d0 p- d8 x  Z, X6 R: L# [           int p = bSearch(nums, found, higher, i + 1, nums.length - 1);
* d9 d% s! O$ s           if (nums[p] != higher) {
. H! U& j) q- y; T               return null;6 v+ V+ e( D0 `- z& d8 a
          }
3 x$ u+ ^4 F/ j* G& O           found[i] = true;3 u2 ~3 [7 q$ F. O
           found[p] = true;
8 M5 E# C# u/ u5 @9 ]; `1 ~           result.add(lower + k);
# \: w, c- `6 [3 i" G      }
3 r4 q( W. ^$ Y/ l       return result.stream().mapToInt(i -> i).toArray();% _+ m& d& J$ \% X
  }
1 W* l& d3 W& ^8 F* b
/ z7 K, n) H4 H3 W2 R   // 在 [l, r] 中找到第一个 found = false 的 target: H' R. `- g0 i. M1 Q/ ~* T
   int bSearch(int[] list, boolean[] found, int target, int l, int r) {
3 h/ @' z$ Q8 d" i6 R* ~- `       while (l + 1 < r) {
, G5 f4 \/ o; U4 |! A9 \           int mid = (l + r) / 2;" P/ H+ P% m/ F
           if (list[mid] < target || (list[mid] == target && found[mid])) {
& v# H. B$ C1 [/ h6 A! N& K5 p               l = mid;* Q; S9 c) f( L
          } else {
" [) C9 `4 Z- n4 U# o2 }' a* c               r = mid;
5 f$ m" K6 Q9 Y9 l4 @          }
4 n! B# G- l. X      }  E% L1 C' P) L9 u; n
       return list[l] == target && !found[l] ? l : r;
5 a5 I/ ]1 g: C: Q: w  }
# Y* i. n: m' D( M. t}
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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