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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
关注我们:杭州上岸算法网络科技有限公司/ R: ~. n6 q; m9 C* c) C
【 NO.1 可以输入的最大单词数】, n, Q  W8 O( r# K0 {. q8 k& A
. X! Z: y, M- P) y: a6 B  F
解题思路! U. G+ R' |9 l! S
签到题,循环遍历判断即可。1 |, E8 v4 z& h
3 q' R: O+ J5 s$ U' J6 S
代码展示- r7 K9 Q, ~+ p; b/ z  `

( O- S1 B. _( L! U1 Bclass Solution {
: z1 z  @( k8 C7 x& b. E    public int canBeTypedWords(String text, String brokenLetters) {
7 h7 S8 y6 v! ?        if (text == null || text.length() == 0) {
* G& W6 S6 _+ \/ N             return 0;
, S$ N; ~5 ]4 o+ O$ B8 f* f        }
, ~9 o# T' t/ ^) N# y1 I( v        String[] texts = text.split(" ");
1 e% R1 `6 Q( A4 }/ \$ M) t        Set<Character> set = new HashSet<>();, J( ~9 g7 `- p. @8 V: b: t
        for (char c : brokenLetters.toCharArray()) {6 N) {2 o: g# m, I* z% ~) ~
            set.add(c);
: g- j( O! e8 \        }
$ {9 x# |% O" R6 c7 b8 E# _        int ans = 0, flag = 0;# s  [8 o- \2 k* Z% m' ^5 R. @9 Z
        for (String word : texts) {
4 J/ n0 P* p. g3 a: N1 Z- h            for (char c : word.toCharArray()) {2 j6 `& O4 E' B  t
                if (set.contains(c)) {) V+ H# r* Y: P4 a
                    flag = 1;
9 j; x! |* u' e, K. r" ~; w7 ~9 i                    break;
0 ~" }# g- N; v, y( |                }
3 d& r3 s' Q0 ^6 Z            }3 B/ c0 E( u( }; Y; K
            if (flag == 0) {1 f2 _3 Z% N; @* c7 P0 c+ X
                ans++;( M, G# w( ?) s. \9 S% ?
            }
' f2 H: v+ k  r+ I( M7 j6 |            flag = 0;  p9 n: N' v# l% n, s# E
            / K  ]. D% t/ M! z1 T3 b7 v2 z
        }
, |" l, a' {. t7 ^( Q% ~) v        return ans;
  U7 Y& i8 W9 b0 V; S5 }, R    }* @! W, a# J0 l, ]4 R- L' o
}5 G  U/ c4 p" I/ M
  B3 E* S6 M* Y! J
【 NO.2 新增的最少台阶数】% E+ D8 }4 D- R) `3 @: ]

" |% Y) q. M% I+ K; m5 C解题思路3 H, |3 _  H7 W3 B( v' B% C
第二道签到题,两两计算差值,需要判断一下是否可以整除。
, q1 q9 L7 `* x
' x6 u7 ?9 q1 v% P8 |6 r$ P, V代码展示/ ~) x* q% Q; t3 |; u4 L+ O% i

4 P, o, u! Z2 y7 @3 B: R0 uclass Solution {* U' e" k/ S# @
    public int addRungs(int[] rungs, int dist) {
% Y5 O% A; x$ q$ C% l        if (rungs == null || rungs.length == 0) {
: `* p  Z- A( p% q8 Q* O: W- A9 s            return 0;
0 c8 m$ p) Y3 ^+ d; P1 h& t7 C% v" @        }+ o( y0 b4 ^/ N
        int ans = 0;
4 c" x6 C8 k/ O        int preRun = 0;
: s; ]4 @$ h6 W0 g( v- E5 o8 a1 R& h        for (int rung : rungs) {
& ~4 O5 N; Y$ }0 D( C9 ~/ m; B- k            int diff = rung - preRun;
* ^8 z  H; j3 w            // 整除的情况可梯子少一个
9 P3 z; _0 K4 R9 m% Z$ D: |            if (diff % dist == 0) {
6 J; _  {3 s' I, F' K# F                ans += diff / dist - 1;
) R4 E  J7 X/ Y7 k/ Q, r2 g5 C, p            }' i  f  c6 h% o; c; z; {! f
            else {
" h# |: F' _! d                ans += diff / dist;
) s* y3 G+ ^1 s9 g" J3 V5 k            }
% m7 f9 e7 t( i+ x            preRun = rung;4 [/ b6 u$ C4 u- f: B2 u
        }
2 h# u& L; m" Y" C5 l        return ans;6 Y3 p/ V# n+ ~. M. @
    }9 y( }/ s$ i% m4 `& c2 R5 Y
}  P2 ]- b2 {, I- H% e$ e
8 e9 T$ }! @4 `. L% o$ e
4 L" `, t) G/ a" E$ ?' n
【 NO.3 扣分后的最大得分】; |# C/ b6 s' X0 f

7 Z6 N7 v+ v, t; ?解题思路
- C- Z) p3 |: W0 Z4 [* P1 i坐标型动态规划
) i9 F2 h3 ]1 Y& \
) s& L$ I7 p) p2 I2 B: O! ^& |dp[i][j]表示处于坐标 i j 的位置的最大收益
' w4 b6 o5 K+ E2 d' `/ D- W; m6 I6 B  ~8 l& R: N
普通的坐标转化会超时# F8 Z  @% R6 e

6 m/ H& o( p% N0 H2 c考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的$ o: A7 x1 |0 r' D$ X# A
" z( v. P6 o/ O3 ?. C! b
因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用4 a6 w- \7 o7 Q" O# O

. j& r3 [1 Z. P6 P7 h) v+ z还有优化的空间,i 可以压缩成两行% k; y. w4 L+ R8 w$ v# _
: L/ L6 J( A$ E& ~
代码展示
1 }+ p2 b2 B4 a% J" M6 w1 j% |) R  g$ y! J1 W
class Solution {: c" J; v. m+ _. C( \
    public long maxPoints(int[][] points) {
, Q! @8 ^7 s  _: F        if (points == null || points.length == 0 || points[0].length == 0) {; d% d$ K) f$ p% M  T! B
            return 0;
' z+ x( `. t0 Z/ W        }
' ^3 L# i  a- ~9 p        int n = points.length;
/ ^$ L5 E  l, u1 w8 P- A        int m = points[0].length;
, o; X3 @/ v) p4 T4 E& X; ^' D1 H+ s" F        long[][] dp = new long[n][m];
! P# G- e4 Y! a$ V2 P6 S# G  B; Z        // 首行初始化
6 g( H; s" E: M; r        for (int j = 0; j < m; j++) {5 U* S% R1 i% D" }
            dp[0][j] = points[0][j];
8 w' v# @6 U4 A& |        }* f; a) ^0 R' x2 I: I# e
        for (int i = 1; i < n; i++) {. a: b. q3 O" _7 u0 l, ?+ J
            // 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;9 }& ]  w* o3 P
            // 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;
& ~; P" M& z) ]            long leftMax = Integer.MIN_VALUE;
; _; i; a9 G/ p, x" g) D9 I            long rightMax = Integer.MIN_VALUE;
! ?+ I' O% [) F! y! e" n3 [- U            for (int j = 0; j < m; j++) {4 X6 a8 Z$ _( v$ j
                leftMax = Math.max(leftMax, dp[i - 1][j] + j);5 [0 V9 [% W  [. C% t3 o
                rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));7 O& z6 U( t9 F8 b
                dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);. c1 s' [5 ~* L( D
                dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);& |) v6 \) R+ g
            }) y$ J+ ?9 f: B
        }, H- ~# ~8 f" Z8 Y" |
        long ans = 0;! `5 W2 m; E+ d5 }" W
        for (int j = 0; j < m; j++) {
% O8 s2 B9 a7 E! \9 Y            ans = Math.max(ans, dp[n - 1][j]);2 E& n# h! \  m+ }: R; }2 `
        }( F: u0 Q) M$ F. e0 a7 I  N
        return ans;
' q: r; G2 U  y7 Y    }# A' f+ l* U# m( I
}
, Y9 ?- ^3 @% p7 \1 J( c- {; p1 K1 C" o6 a  a

$ |' D: h1 d9 X7 l3 b) G【 NO.4 查询最大基因差】
2 d6 t% M. s* \( s/ x& L( K6 W' U8 Q" W( m
解题思路  T  l  o5 [8 l, ^1 w
二进制的字典树:将数字转化成二进制记录在字典树当中
. H. T; _/ v, e/ b+ K0 I" x1 r+ G6 H& ?) ?2 b8 m
构建树,方便做DFS
+ e' V& }, {+ D/ P2 o5 ?9 U0 a$ F3 |1 m2 ?* m# J
每搜索一个数字,将该数字更新到字典树当中
  a3 H: r$ I  `! i3 G$ ]& {! P/ R2 Q
在字典树上计算最终最大的异或值4 R+ `5 J  S! b4 b' q: ^

4 `7 }7 d: x3 ?2 a代码展示' Z9 L' ^, f: A
6 K0 r, x) @- [1 p8 w% O6 r, r) A7 }! Q
class Trie {
1 \% r& e' s# r! O    Trie left;      // 13 O8 g2 `( \  a- I5 V2 D0 r
    Trie right;     // 0
. z( B# D2 E' b# ]    int[] count = new int[2];1 m& u1 M' u0 L9 V+ u
    public Trie() {}
( A+ P9 i* U- j6 Z5 K" d; Z& f; F0 c  S
    // s == 1 添加, s == -1 删除
4 F; m) C3 @# q* P0 I    public void insert(int val, int s) {: t* o2 T  r* D1 b: H! ?! D
        int flag = (1 << 30);
1 v2 M; l5 x6 k0 @# ~1 [- E        Trie node = this;3 B) k7 G" B' a6 `# z
        while (flag > 0) {$ G5 Z1 ~: v4 i
            int bit = (flag & val);- t+ v, k  s. l5 Q3 O3 c
            if (bit > 0) {
# K2 o  [' Y) ]& {$ z$ \0 p                // 1 走左边
9 |4 |5 S" f1 K* |                if (node.left == null) {1 ]* @4 t6 ~2 X. s8 i8 s
                    node.left = new Trie();
3 T+ p& Y8 G9 f. K                }9 E9 i1 X; l6 f5 h+ L# r4 ~% j) D8 u
                node.count[1] += s;# U- x+ C; s, T
                node = node.left;6 W+ E. U  Z) b) r$ j
            } else {9 p# e# @; _2 }: F4 w: b1 j- ~
                // 0 走右边
% J; h9 I5 e; T/ S/ _. T                if (node.right == null) {0 F" U4 T/ G1 w9 i+ ]- M
                    node.right = new Trie();
( e! s% {  r$ \                }/ U) x( g- y3 E* T1 }' I$ q) h2 W2 }
                node.count[0] += s;) S: g4 p. z! ]* h# c  y- m* b( i
                node = node.right;
+ J4 r. _- e! \3 l% d            }
: k, y+ X  Q. u, S6 Q* W3 b            flag >>>= 1;
) X1 G. h( ?! F. L        }
# Q. K+ i: x* l& o0 u3 f8 e2 u2 w* e) V4 W    }& c- A& E. X6 s5 V' E

  ^2 n9 D+ V( Q! M+ k" j+ t  R/ C    public int getMax(int val) {
2 n6 V4 e, w  E        Trie node = this;
2 I+ J* n2 _# e% K! f* Z        int flag = (1 << 30);9 x+ a9 Q2 m( X0 x$ l9 a; H
        int res = 0;( O. n$ C! i2 Y; j7 c, t: p
        while (flag > 0) {  j0 i; ?$ a; q# q9 {3 V3 J
            int bit = (flag & val);2 F+ X9 F7 o/ E6 P- W! y% d
            // 贪心算法,1 的话走右边,0 的话走左边
3 K5 r* M, Q* h8 t, n9 k            if (bit > 0) {
6 C0 M* |5 a0 W  x; V$ B5 x% i# h                // 走右边,右边不行走左边% K- y3 s% Y  l
                if (node.right != null && node.count[0] > 0 ) {
% S: G! L4 G5 M1 I4 E' {8 I                    node = node.right;
  @4 D, ^5 G8 W" P' O# i                    res |= flag;
0 \% B% R1 _' F4 s! _- T6 u                } else if (node.left != null && node.count[1] > 0) {; ~5 j8 \4 D8 c9 @
                    node = node.left;
5 c9 j4 ]- L, }+ [* F                } else {7 C+ F$ a3 g" |0 ^6 U. X  j# Y
                    return -1;
, M$ t2 Q% Q( _8 v' G# D                }
* [/ u3 w- S! N( Q# [& L0 o- V            } else {% C- y6 w+ Z6 M7 |3 d1 Z5 }6 s
                // 优先走左边- A" U# l  X/ k9 ~2 |" I0 c
                if (node.left != null && node.count[1] > 0) {
) u! c+ ^0 R# d* j" \) Q. w                    node = node.left;( Q- J- J2 I; a* J+ I
                    res |= flag;- V1 h$ g6 M4 ~1 v, l
                } else if (node.right != null && node.count[0] > 0) {: `3 w- w' t! w- |2 m4 p9 M
                    node = node.right;: ^0 X9 k- [- E% Q% g
                } else {6 `8 p' W1 `) E& l( X1 I
                    return -1;
) ]8 }; u2 L/ l% b3 R                }
6 _( @" H( Z% B" ]" m) X9 B8 e3 R            }
' ^. R1 z1 W) }  v5 L0 @: b            flag >>>= 1;5 Y7 H, y) M; _2 |& C- W
        }
! m: ~, W- b# K1 S" Y$ \2 S        return res;: B9 H& X8 D  \( L( O% M( n
    }
$ Y7 ]5 M- Z  }$ N9 t8 N}6 u4 y$ f/ G4 j2 d+ V! z
public class Solution2 {6 l8 {5 }+ O) v/ b5 Y6 ^6 ]+ W
    static class TreeNode {! ]! W( U$ ~$ [7 _8 n
        List<TreeNode> son = new ArrayList<>();
9 h# ~; L8 r5 ]        int val;
7 Z: l' |% A. g, M2 F* `. I" G        public TreeNode(int val) {
6 O* `: V3 h4 N8 S4 Y            this.val = val;
9 f$ D/ @  T9 ^! T' o5 v/ |        }
, p" W( B) ^4 c$ a) C) ]    }
% ^: j5 g) u4 ^. H    Map<Integer, List<int[]>> map = new HashMap<>();5 k2 o; f, @; u3 W, D. s
    Trie trie;3 m9 b3 V! ?+ e: }
    public int[] maxGeneticDifference(int[] parents, int[][] queries) {
# }1 u8 ]( Q. y8 w( Y" {' S        int n = parents.length, m = queries.length;
4 N* F% B. @5 l        // 封装查询的信息
" N) O$ p6 o4 n- l. r. r; j! F        for (int i = 0; i < m; i++) {, K- }3 Z" W& ]
            int node = queries[i][0], val = queries[i][1];
. L  i4 E6 s6 c- i            if (!map.containsKey(node)) {
' q: T$ @8 y, i' \6 A                map.put(node, new ArrayList<>());
3 K( q) {9 ~, k            }' I  h8 D, y. y
            map.get(node).add(new int[]{val, i});
  i1 i& h" [1 F( O8 c        }
9 ^6 v: D, R& H1 d        Map<Integer, TreeNode> nodeMap = new HashMap<>();
5 y+ W+ ~: L9 h% P& X        // 构建树
. ?" c0 X' A, ~9 a: M        TreeNode root = null;
+ N  v4 n$ h1 M- ~" E3 V        for (int i = 0; i < parents.length; i++) {, _& D2 ~0 x! P* `3 M5 H: N( C
            int p = parents[i];& V5 `& g$ n  |
            if (!nodeMap.containsKey(i)) {. b1 e# X; {2 l8 J- m8 F% ^7 m
                nodeMap.put(i, new TreeNode(i));
4 H7 u2 @$ l" \' u( c* V7 E            }- m+ m+ f# a2 L8 O1 _
            if (p != -1) {( Q8 P# u: a! }  L
                if (!nodeMap.containsKey(p)) {
; e( T2 H" |& b8 Y* |                    nodeMap.put(p, new TreeNode(p));
1 }# `( R$ o% U  `& l  W                }5 w/ N+ ^" }! ?$ {7 @1 G
                nodeMap.get(p).son.add(nodeMap.get(i));
" D/ S2 d0 e# c4 x+ d8 P, |            } else {! d8 s5 F* E. v4 t$ p1 s0 e+ |7 P( L
                root = nodeMap.get(i);9 c. p* i# c# n( G
            }
3 f* {/ z) O8 a# I2 P* B9 s" Z4 s        }4 y0 Z% j" N8 T$ I
        trie = new Trie();
, N* B# l) [7 R- \; n        int[] res = new int[m];' I) Q. L. \7 q+ k5 i2 F9 ]
        // 在树上进行DFS
7 E: {* N  s" C( T- P8 q        dfs(root, res, map, trie);. b5 v0 F, G5 I: e
        return res;3 O; w9 e9 L+ v" Z; @$ E

  C% m$ U8 t" A    }% P2 O8 m5 Y9 p
; u5 B% H, s5 B" a5 n6 L( @" h
    private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {
! w# z! Z- g) u2 k* J        if (root == null) {
1 C& x: m; F" |" }  x            return;9 t2 O" K, b7 A! ^: w
        }5 C- |& D% o& Y& n- C* U4 [$ O' \
        t.insert(root.val, 1);
7 E1 }) W( Z% g: K/ J        if (map.containsKey(root.val)) {! q5 t+ g4 Z. `! D  Y) D' `
            for (int[] each : map.get(root.val)) {
  H0 M* i; {0 f                int idx = each[1], v = each[0];# l2 A" {* |( n5 o$ f; f
                res[idx] = t.getMax(v);5 i; Z9 d# X9 y( `4 B
            }% z! ]% k: d+ A6 L
        }; J/ w3 X0 q+ t# n! |7 b
        for (TreeNode s : root.son) {
8 I5 ?* _  O  S" Y, p  B' \            dfs(s, res, map, t);
' w: [# q0 p/ O% H6 p# [0 Z        }6 j7 O2 E7 D# l) D7 t" A. o# j
        // delete
; V+ I: {& W( a# U0 g        t.insert(root.val, -1);
4 m7 y; D, Q! V* x1 P" s3 o3 p    }
6 c  G$ r& p6 e' ?- @7 h' P5 |4 Q! A}$ h- T+ ]1 |1 w9 Q: c- Q# Z# L
( u0 a6 \/ w$ n- B- [
8 i. S* A5 c$ f0 j6 [$ U
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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