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

[吹水聊天] LeetCode Weekly Contest 250解题报告

上岸算法 回复:0 | 查看:2966 | 发表于 2021-7-19 18:02:58 |阅读模式 |复制链接

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
关注我们:杭州上岸算法网络科技有限公司: o' K- I  S! `* p0 ^
【 NO.1 可以输入的最大单词数】
9 l- o0 H: a+ O4 ]
% A" e: C0 l2 w$ O7 n解题思路: \0 d* ?) c1 N  N" ?; n  S; E
签到题,循环遍历判断即可。4 Q0 }5 R- s+ A

. |' ~  t! U6 b: _! }. w6 g/ P) v代码展示# p- l& t+ N- _3 Y" \" {$ M

4 y+ c; M8 O2 h$ `! M4 d) Kclass Solution {5 a" j9 O2 w' r3 Q6 N7 ?9 J
    public int canBeTypedWords(String text, String brokenLetters) {  H& x* X) D! {0 r0 B# F
        if (text == null || text.length() == 0) {
  {- o( e- @. }! B             return 0;2 H: w; k- ?0 n1 r
        }
; T' H& v) [2 _% {        String[] texts = text.split(" ");
6 Z2 Y# x4 t6 D: ]6 v        Set<Character> set = new HashSet<>();0 X4 Q. @9 N! p+ {
        for (char c : brokenLetters.toCharArray()) {! e) u: O1 U+ ?2 c# F
            set.add(c);
7 B! n1 A. r( P: K- V( s( u/ l; |! V        }
/ _- f+ |  `; ~5 c        int ans = 0, flag = 0;
0 b5 Z7 U. o. T2 m5 Q; l        for (String word : texts) {
& @0 ]) z0 S9 R7 i. Y' b+ {3 _% [            for (char c : word.toCharArray()) {
  h# `" C- F( l! j& p& E                if (set.contains(c)) {
+ U: |) |( b  b# a& `( ^: \+ {+ H                    flag = 1;
' [) a  m* S% k                    break;
+ n3 r  A5 j* B0 P                }6 y/ T3 ~3 I& y' @
            }
, e. E$ a0 `/ |# r+ z            if (flag == 0) {
5 a$ P8 @2 }( e# u, V                ans++;5 N6 q- L6 a$ {3 C: h6 p" E
            }4 ~0 {! u; }4 k% Z9 c. C% t2 j
            flag = 0;6 F2 d4 p8 Y: y( t6 L
            + ~7 z; D0 ~* Y. j7 _1 t0 Q
        }
" ]1 i" f0 {9 L# t7 I5 x        return ans;
+ \3 j9 G6 c& z9 Z- }/ I    }
8 l8 M# I* @- o  w2 F- Q4 c5 ]}
/ r' g% H7 V: @: h* x- B  m& p/ }+ i) P) S; m+ D( _3 v
【 NO.2 新增的最少台阶数】
- }7 w7 X# X6 l5 M, a) c9 c( Z1 J5 x( [' p& d. E) o
解题思路
6 _0 s  \( ^( X& {0 b0 Z第二道签到题,两两计算差值,需要判断一下是否可以整除。
  @# d+ ?/ ~: V, {6 ~. R
7 B6 N7 V4 C) ~0 |: q4 B代码展示
0 L5 h( k6 T+ f, s3 D
- _+ P/ W4 ^5 ?% y! g- p2 Sclass Solution {
$ T# ~. I1 s7 T  h6 r* Q    public int addRungs(int[] rungs, int dist) {& @  D- ^! G" d' j1 h
        if (rungs == null || rungs.length == 0) {
/ w" B1 T2 j2 n8 e            return 0;0 Q& E# `5 V) D3 m( h0 w9 n- ~5 M5 ^
        }/ M& k" o8 F, N8 N+ x# C- p
        int ans = 0;0 [. \3 z2 _$ Z! g2 O" g
        int preRun = 0;6 B. ]3 ]$ q' G) ]; F
        for (int rung : rungs) {, P; P$ h+ u. t' {/ K; _5 {( I" ~
            int diff = rung - preRun;
1 V7 m8 o5 ~' Y( }# D  V$ X6 F& p            // 整除的情况可梯子少一个
# x$ N. j/ v5 L            if (diff % dist == 0) {( u% _# q+ ?8 d' O, F
                ans += diff / dist - 1;
# n3 E& u& F, K$ ~7 W            }  o' Y8 K! v1 |
            else {9 Q, q1 r# o  i" o3 k6 Y
                ans += diff / dist;
* H7 {7 }* K' N9 S( \% x            }
* p" G! m- D- S. u2 m            preRun = rung;  y' B7 V, O, Z3 A7 @: d8 f- I
        }
. I6 s9 ]9 S8 m" }* c) r2 u( X        return ans;8 M$ A5 p  n; G* x
    }
7 z: [9 t- m) z/ I3 _}: [9 U+ Q+ \& a0 H$ x; P! v* ~. t
7 E2 l, }/ b+ a' ~+ r

+ }! A4 y# V) d' X  c: Z【 NO.3 扣分后的最大得分】
! t* L2 b/ W0 v* K9 r7 p8 Z# g" K# `# H
解题思路
# w& a9 a9 [/ r4 u7 G: j坐标型动态规划
+ R, Y9 T0 V9 s$ F- t
$ J; a! `& m/ f/ B8 Vdp[i][j]表示处于坐标 i j 的位置的最大收益
, N- F8 L4 g3 w7 Y* {4 B! l& }4 U7 \( z( A  g/ G  Q
普通的坐标转化会超时# ^' O. g& F( @. H7 r6 j

+ }7 k/ \# @! C* Z# r+ R4 E9 V考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的
6 o* R' ]' _$ s, h5 ]
( N, X7 L" u. ~& @/ X( w6 t% ^因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用0 E% G; t, l6 X- X

/ I! q( W' O7 K# I0 W- F) _还有优化的空间,i 可以压缩成两行
+ O; u( h/ a4 N; p3 ~& A, L( \5 i! b* e+ S6 {3 Q* F, Z1 M  U# P
代码展示
" J8 \5 t+ l; c" r. P0 V* S2 {! z  c* Y7 X
class Solution {7 s% k% s9 Q6 l: [
    public long maxPoints(int[][] points) {7 L9 c: O/ u2 m
        if (points == null || points.length == 0 || points[0].length == 0) {0 Z2 ~2 Q5 H& n4 a& O1 r( f. U3 r
            return 0;3 o" w* |, V- w! t
        }0 a- D- x1 d' P. A5 {7 X  C6 o) x
        int n = points.length;
+ N' F8 q0 i2 \        int m = points[0].length;
" n9 C$ e# Y+ |        long[][] dp = new long[n][m];
" a& P3 M' I9 F  h5 q        // 首行初始化2 Q. k. \# F, M0 }
        for (int j = 0; j < m; j++) {
, k  p* X1 y9 ^7 ^+ y1 X            dp[0][j] = points[0][j];
* v0 B3 H. b$ @: D. {+ Q        }
* y+ j) a0 `8 r' s        for (int i = 1; i < n; i++) {5 @; [8 I$ [+ l  @  m
            // 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;4 ~+ A. I, V; Y. H6 w
            // 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;
8 T. ^+ m. v2 \, M            long leftMax = Integer.MIN_VALUE;
. y, ?4 K" N& p; ?1 v3 {$ [            long rightMax = Integer.MIN_VALUE;
. h0 T4 L( J1 i- M+ u- S" M6 q            for (int j = 0; j < m; j++) {
. A, a$ f" B& Q0 Q# ~5 @! ^, z7 p                leftMax = Math.max(leftMax, dp[i - 1][j] + j);; a- ~7 |5 z; u
                rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));  ]: V- l2 O" n
                dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);3 L+ ^& i5 E/ D' A
                dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);
4 X+ c( [5 j" c; ^            }
6 |' u2 [1 Q$ e1 a* h        }0 S. t+ \. e2 d/ u+ F6 M( F$ n2 j8 o( u
        long ans = 0;- W+ P, Q+ M4 v4 V
        for (int j = 0; j < m; j++) {& X- V/ W! j. f8 s  f
            ans = Math.max(ans, dp[n - 1][j]);1 d/ O3 f' _& R! Y' b; Y$ E
        }$ N5 T% i- a% h. L# [- D5 F$ Z, m
        return ans;
# v9 c' G5 r- ?$ g, D7 V$ r    }3 N3 j7 n5 s2 I1 G* P
}
: R' C+ y+ G* f" E- a
* s& A/ P5 G  [$ k0 V- ~2 v$ i
: X0 O7 [0 d! E! r【 NO.4 查询最大基因差】
6 [  a* S' h) U$ h' c0 V. E7 ^3 p, }" y* N' w  s
解题思路
" q, \0 z" o& O# O# G! X二进制的字典树:将数字转化成二进制记录在字典树当中8 l# O$ l, J* w0 n9 }0 @5 a

' J% X9 s$ ^# K3 }# X3 Q构建树,方便做DFS! }8 }% Y! _! J& D( ]. ~

% i0 H- w6 n: r# J$ x4 @& ~  t每搜索一个数字,将该数字更新到字典树当中$ q' W5 x8 w4 z9 g4 L  H

! u: b' {' Y: s' b* w在字典树上计算最终最大的异或值
8 E* U- |% a2 ]! \9 [3 G# g& [  M( }9 C3 Q/ [
代码展示6 }9 C) K+ B: I' b, r  @4 O
0 M- r3 e3 G$ k7 q
class Trie {
" x% F$ J* V6 n5 F9 T2 G    Trie left;      // 1
1 i4 K6 C3 b- `! b, I1 ]9 P- [    Trie right;     // 0# E- F% ?0 r: i. w) x6 B
    int[] count = new int[2];
/ D( t! k  @" o( i    public Trie() {}
& I, K  |5 u3 N1 h9 y
& Y; U7 ^% u0 P. A% O    // s == 1 添加, s == -1 删除, i  l8 W# n. C5 W
    public void insert(int val, int s) {
4 A& g# g  E1 R- q, x* B' h        int flag = (1 << 30);* s' V- Q  E, ]/ o
        Trie node = this;
* Q* X5 O& V9 Z2 @$ H        while (flag > 0) {
: j/ W. u* C# q  n4 v) M            int bit = (flag & val);
0 d% j3 S' [! C4 _            if (bit > 0) {
5 n0 ?; m& _3 a$ D6 t- t                // 1 走左边
6 f! c% [2 q7 N2 t7 p                if (node.left == null) {- @. t2 F+ u, w' I" G+ G+ A
                    node.left = new Trie();
* z: J! o8 X7 ^. `                }
: \& o0 F8 ?$ @) O; r! L                node.count[1] += s;
$ O5 e& I' O+ E6 N4 d                node = node.left;
- L8 u) V4 m3 m$ ^            } else {
7 N; F- M3 M# o/ L8 v                // 0 走右边
) i) E3 d; ^4 ]& l, S$ T5 T) E                if (node.right == null) {
3 F! o' A* E% v$ G) h. `                    node.right = new Trie();4 q# v+ W- n3 e5 N
                }7 B, U. Z/ A! x9 @
                node.count[0] += s;
8 e1 S: X# X4 j5 t+ `2 |# z                node = node.right;
' i+ T. J# w" e$ |1 X& ~; d" z            }& x# X/ d# K/ O6 l  E  ?/ T' S
            flag >>>= 1;* R- A# @5 v9 d9 T) r+ @, T
        }/ c6 j* n5 @3 m- m' D. ?
    }6 ]0 m- \3 r- s8 |( t, Z
) ~9 `1 e0 x' I) @* D
    public int getMax(int val) {
! u; D5 D, G. M# }9 D& \4 y        Trie node = this;
. V- [: `- {; v6 h        int flag = (1 << 30);
: Q; Z( B3 ~/ S$ K        int res = 0;
2 O( M- E( d/ R3 ]" \# h        while (flag > 0) {! P! y" a. @& F5 L
            int bit = (flag & val);
' H% q1 o6 h5 w7 }- m' A- K            // 贪心算法,1 的话走右边,0 的话走左边
1 H& a( Z$ [# T1 e" G            if (bit > 0) {( [0 h- k3 B3 O& o9 E' W$ H
                // 走右边,右边不行走左边
- P3 e& H0 A0 F                if (node.right != null && node.count[0] > 0 ) {7 R" ?( i! Z9 [  G- F. B* q$ ~
                    node = node.right;" T% {2 z; p. V& Q- j0 G
                    res |= flag;9 E) h1 g6 Q- b/ o; Y
                } else if (node.left != null && node.count[1] > 0) {
. r' k6 j5 z$ `* S; W                    node = node.left;3 C8 y. h( F( R7 A1 r6 s" T2 \
                } else {5 Y1 Y( F6 N4 h. l  E
                    return -1;
7 c3 ]5 w, N1 e5 r; t                }
* d5 x$ y9 F5 k" o& n) E            } else {
4 C; a3 ]" ~; {( p% i* ~: U/ B/ f                // 优先走左边: ~& h+ R" k* \5 _! O5 B8 m
                if (node.left != null && node.count[1] > 0) {
: m- D5 O" {" u                    node = node.left;4 F" ?+ `  K1 L, D" b5 D
                    res |= flag;( N7 s, Q( |, I. E' ^" C
                } else if (node.right != null && node.count[0] > 0) {
. U+ `% H5 j0 ~                    node = node.right;/ W0 W, F7 `; [5 y' i4 p
                } else {4 V% f( ]1 x% {& j/ a
                    return -1;( E$ M' }; N4 f  f$ p! V( c5 D
                }' C  ]5 E* B1 m. B  ]) x
            }
9 M- V( |: P8 Z( v/ E7 j- K3 _            flag >>>= 1;* Z; Z. E% u1 g8 o
        }
1 k; e$ `; c: V, W* v        return res;
) Y6 g. ?, t1 d, B. D    }1 W/ J& g. a3 h+ G
}& r3 l0 {+ Y% C. T( D4 r
public class Solution2 {
* {6 C- j1 F/ M8 Q. Z    static class TreeNode {) V, Z5 M4 [/ H& \" R) |
        List<TreeNode> son = new ArrayList<>();
- H6 `! I% J6 q6 l7 @: ?4 S; ^# u0 z        int val;  E3 R% Z. y, I$ G5 B" }
        public TreeNode(int val) {
, L7 t- f9 x. B: ~$ F( O            this.val = val;
, e0 w# L& q6 @7 z1 ~8 {+ V        }
4 y0 b* R, ]% U. N4 ?    }& R9 P' W4 x3 D. j  @
    Map<Integer, List<int[]>> map = new HashMap<>();
% c; q$ ^: A1 r8 |    Trie trie;
; A: j$ L6 Z5 j8 w/ {0 E7 r2 A    public int[] maxGeneticDifference(int[] parents, int[][] queries) {" k$ `6 k; i, Q1 n+ Y" D! B, H7 n
        int n = parents.length, m = queries.length;
  X' c8 U% ^  l$ N" {4 F        // 封装查询的信息. I5 L( \7 X# x: D1 \
        for (int i = 0; i < m; i++) {/ _6 |8 f* s' O$ S% Q+ a
            int node = queries[i][0], val = queries[i][1];
. M( ?2 C0 ^: O0 M            if (!map.containsKey(node)) {
7 v. d- _- g1 F- s, t4 n                map.put(node, new ArrayList<>());
5 |1 P% j/ V6 e4 X3 P( D            }
4 a. L" A1 t4 {& O+ h2 [9 _            map.get(node).add(new int[]{val, i});
! |  H8 r. b+ p/ g+ G' I4 ]8 I  L- \        }. n* h1 Y: z1 @; Y/ n! N! B
        Map<Integer, TreeNode> nodeMap = new HashMap<>();
# t- W6 l) d: P        // 构建树
" J. H$ \6 i& T2 |- J: e- b9 G        TreeNode root = null;: Y; Q7 g7 a4 f# c
        for (int i = 0; i < parents.length; i++) {
9 x! @% K! r- c" Y2 y7 \4 a            int p = parents[i];+ L& h1 x$ [( k* K+ r0 g5 U
            if (!nodeMap.containsKey(i)) {# `; K) {3 l% \+ C1 \; x
                nodeMap.put(i, new TreeNode(i));0 t! j+ G. w4 y9 Q, h
            }
1 F" P$ L1 j& C8 P  t' a- M6 c+ f            if (p != -1) {
: u: t% |: r) ~2 j' n* o/ a                if (!nodeMap.containsKey(p)) {* W0 |5 [5 @! M0 T$ N
                    nodeMap.put(p, new TreeNode(p));
5 E: E' v4 B, ?; v6 L                }
, Z# F5 ?( j- F9 V) B                nodeMap.get(p).son.add(nodeMap.get(i));: X0 G9 A$ Y* c, N' ?' ?
            } else {
/ p  @- s3 p  }0 s$ b0 t  T7 o                root = nodeMap.get(i);
$ Y; b# K# o" S            }
1 U, D& h/ J! I  a! m: r& j, N        }$ _: x; Y% m. E7 h1 ?: _) g0 g
        trie = new Trie();8 ?& F) _& d% Z  {, j+ S5 i1 r  c
        int[] res = new int[m];
! Z2 u+ o0 U5 t0 @' ?        // 在树上进行DFS
; D+ r5 c8 Z3 i( n' ]        dfs(root, res, map, trie);
8 I; h; @# {# M2 e% p        return res;- r. I: h- Q. l" t7 k! r# i5 Z

3 B( k7 m8 ^- |    }* C4 e$ ^, ^7 d" w! Q
8 l% F- L' z9 k) n" }; y- I9 A* T
    private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {
! K' K# @8 S; r6 z        if (root == null) {
6 l* z1 [* T9 Z  w' ~% {% @            return;: V5 g  f( g1 t/ r! @/ N/ e3 V/ [
        }! q5 X$ P# G7 g: v# t
        t.insert(root.val, 1);
& ~7 {( ?/ y  y( C- w        if (map.containsKey(root.val)) {
% E, z" f8 U4 G: A* K            for (int[] each : map.get(root.val)) {7 D. H2 _  Y0 X$ N6 [6 |; s
                int idx = each[1], v = each[0];
9 A( e3 X$ a: c' v                res[idx] = t.getMax(v);
2 J0 [2 a! U% U) }$ f            }
8 v' r" ~% l7 e! R- V        }
2 _  l, h- E3 v9 P% i; Z# G        for (TreeNode s : root.son) {
" C. R9 [# y2 h' v+ y            dfs(s, res, map, t);
6 {8 j6 l' m5 S! x        }
- \7 t$ A) |6 g! w- E/ i. F( A        // delete
$ l" T  B; R" @5 Y7 X; y        t.insert(root.val, -1);
+ q2 n: e7 E" ]3 y8 q  ^( R    }
4 P: g! M; R  T, y1 h}
) i% g4 ^/ `( w2 ^" w
; _& z9 b( F) s- h/ \$ ?7 q; ?2 v9 N! a
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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