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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
关注我们:杭州上岸算法网络科技有限公司
, J/ L3 P& O7 o【 NO.1 可以输入的最大单词数】
3 J- N! x  a! ^5 d) r% j" v/ E" R( M% I
解题思路$ V$ L8 p0 D5 p: U' X: P4 `! v
签到题,循环遍历判断即可。9 i: U' c5 {4 {9 [

5 X9 P) u2 x" d代码展示
0 J8 e. t( N) [+ \" ?* q3 J3 X5 u+ I
class Solution {
1 @, a: G  v; I$ {( ]    public int canBeTypedWords(String text, String brokenLetters) {
8 \; }/ S+ l; b/ [/ T3 `        if (text == null || text.length() == 0) {6 k) a6 J" U8 J6 o
             return 0;
% a- Z" y$ v2 j' ~        }
+ `2 A$ m( F' Y1 W8 l        String[] texts = text.split(" ");: q% j# I4 \  n$ o8 o/ z  L% G' d
        Set<Character> set = new HashSet<>();" i8 R* P+ V0 F8 H8 I
        for (char c : brokenLetters.toCharArray()) {
4 P$ f# a$ o- f            set.add(c);
3 k- g0 V& X8 m- v1 q" h" x        }; q, T: S+ o2 |% t/ v/ ~- |
        int ans = 0, flag = 0;
" ]1 T  ^0 `7 o$ g% z, r' |        for (String word : texts) {
8 z9 B( V. A! K2 o, O' f            for (char c : word.toCharArray()) {+ R5 f3 E8 [1 l( X3 d. O5 D. D  L
                if (set.contains(c)) {7 x1 h% r7 S8 P  ]2 c3 S) O7 z
                    flag = 1;
2 O+ g+ c2 X# S& z# N# k$ [. P                    break;
8 }- L, l5 @! |% x, J2 Q5 k: O                }! S# d6 _8 u( ?; J/ n
            }/ y9 U3 y9 c! |' h
            if (flag == 0) {; h/ _( _" ^& q7 X5 w' i5 g/ F0 B/ C
                ans++;" Y- j9 J: t+ n% x1 @; r
            }6 I6 L8 T3 a, i4 f. |" Y! y
            flag = 0;, G+ o& c7 r, t5 T0 ]- R# @
            2 N; P2 G: q/ g$ {3 B' o, D4 _/ K! Z
        }
3 X- |6 O) P3 f( ?7 z' v  @        return ans;
  \8 a7 [4 K, h! ]" ?7 g    }3 ]) v7 F% r0 n! W7 G& ~
}
, Z8 c7 r$ W% Z2 x% m3 \- X" I3 {% j; F: l7 \
【 NO.2 新增的最少台阶数】) \" g1 M7 D, W9 N  d0 j) p8 Z

1 p2 I4 i5 \2 C6 I/ d解题思路
( Y: T. d8 b! u% q# ]1 f第二道签到题,两两计算差值,需要判断一下是否可以整除。
5 G: k& p- ~3 l; `! i* W! U' D) m1 f! D6 j$ n) f
代码展示
( _  T) [7 W7 |4 T
3 ]! k, o6 v; R. |& L2 Zclass Solution {
, p5 h8 |) z+ p, z, v& |' H. }    public int addRungs(int[] rungs, int dist) {  d: ?" H7 |, c+ v
        if (rungs == null || rungs.length == 0) {
5 K( s* a' m0 w            return 0;& G4 V5 }  P3 {3 Z& D0 S
        }2 b' z  m6 }! c% l% F
        int ans = 0;. z" z$ i" P/ ?! d
        int preRun = 0;
! ?4 F. v: [- [        for (int rung : rungs) {
/ g) ?2 ]* O8 W: m# l9 B            int diff = rung - preRun;' b. f) e2 s/ P6 a
            // 整除的情况可梯子少一个
. T+ Q1 p: y9 G+ x+ W            if (diff % dist == 0) {8 d( m( m. L! u' C* v  X! `2 b
                ans += diff / dist - 1;# g8 q+ p! i! `4 Z9 _0 V
            }
) T' Z/ D$ ~6 ~0 \% J' b9 j            else {
$ k0 D7 g6 B; z                ans += diff / dist;( o5 ~& H' \* R: N
            }# j* s) o9 J; K" m% ~3 g! X
            preRun = rung;8 k$ p# {2 @' [+ r# L* c8 g
        }
' ^. c6 i7 }( [% y3 O4 t5 l        return ans;; m+ H" I3 F- j7 A- C. l
    }
5 e" D6 ]/ O' |7 t1 v3 Y}
( U1 |9 Y9 e  y2 n. w% k8 M. n
) `- B9 d% G' e$ q
' t8 z, d6 |7 Q% h3 H【 NO.3 扣分后的最大得分】! ~) ?3 {6 R, H# W1 `" K( b
6 {' K) w* I" u1 p+ b4 E
解题思路
* C5 z) ?1 n4 r6 R坐标型动态规划) J$ [. \7 U$ {5 m' w
6 G! e' A8 _9 Y
dp[i][j]表示处于坐标 i j 的位置的最大收益
( T/ f: `9 v: E& t" h
6 r4 Q; r( Y) |$ {, D普通的坐标转化会超时) N; \4 q, I2 d. p& M4 k7 Q

- D  e2 j6 O+ a" {8 n$ P考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的1 L& w- }; F' J. B( b9 \
0 d+ ]; z3 G' ~3 r; i5 W0 H- N
因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用3 k( T% ^3 j4 q1 v5 l; g( C9 J
% h5 m$ s4 x' Q: J9 z# ~) P
还有优化的空间,i 可以压缩成两行) W. L% c4 @5 L: h- q( {7 p2 ]
' i6 ^9 l4 w7 d& T- H
代码展示
. g- w$ I6 H# S3 K& u/ R  W  N
1 q  G  j/ V. z6 }+ fclass Solution {
6 ^& a3 @4 g0 A4 i4 d2 z    public long maxPoints(int[][] points) {$ e& S/ S; i6 j' ]0 R) b0 a. C* U
        if (points == null || points.length == 0 || points[0].length == 0) {
7 Q: d; n% N% \8 Z) c; C            return 0;
# y* \! a' [/ q3 T        }
+ A8 N/ D/ o; I: o( z+ p        int n = points.length;
- W- |$ e5 M! N& g! E        int m = points[0].length;  E3 w* N2 h: B. ^
        long[][] dp = new long[n][m];
& u* M& N7 n' {  M1 z: }% A        // 首行初始化4 ]# R7 ~7 N, X: n3 S: W
        for (int j = 0; j < m; j++) {
- h7 |& @8 h, x5 D: r: k: W9 y            dp[0][j] = points[0][j];
) h$ Z, Y, o' {9 ^; |5 G        }
' A$ y+ R* |2 E$ B) q        for (int i = 1; i < n; i++) {5 A  B" J+ ^* j8 E  B1 T, `" Z+ B4 n
            // 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;
) }  Y( }8 D! X: G7 `& x            // 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;% K" X6 P5 |+ ?# k) u8 R
            long leftMax = Integer.MIN_VALUE;  N+ H3 E. p, ]# S
            long rightMax = Integer.MIN_VALUE;' f1 O3 \. X' k( o* ~1 ^
            for (int j = 0; j < m; j++) {# x7 P; e# P  C$ U/ y5 a& }
                leftMax = Math.max(leftMax, dp[i - 1][j] + j);7 E0 l* z, |7 |4 h* w5 P0 s' g
                rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));% l: h) Y7 P8 n* R4 ~* L
                dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);
9 O$ ~3 S0 T5 o* y8 h$ b, `  O                dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);& c/ M2 w* I1 _6 U! g' j
            }, x0 J2 N0 n  N4 Q9 S, F  y
        }3 I  \9 o" f% M' C5 E- s
        long ans = 0;
/ q1 T. _3 F8 `! _        for (int j = 0; j < m; j++) {
( |; J/ q) m& k" l            ans = Math.max(ans, dp[n - 1][j]);/ v4 w2 e6 c% B" A
        }
1 B- O0 p1 a" h7 y! V! {& ^3 _        return ans;
) [7 h8 O) Q5 [8 H# N2 S& x    }
' o# x; i# P0 Z) y- T5 d1 R}3 d/ o5 G( r. Q  ^9 |. |
3 N7 o$ h) m' J5 ]

( F' R- t, ], X2 L【 NO.4 查询最大基因差】! G& i3 L, g! u+ Q. p) ^( M
* m( \2 W0 Z& X" ~; V; T
解题思路
9 W, l4 \; f: h5 V% {/ l. a0 ?6 D二进制的字典树:将数字转化成二进制记录在字典树当中. t( _6 a! G( K% F7 l2 z8 q
% U9 a4 r* ^# |# x- e
构建树,方便做DFS+ e. A2 R7 u. k2 c" e/ ^

5 h* R! G( Z! t6 v1 ^4 ?/ Y: z; k每搜索一个数字,将该数字更新到字典树当中
+ d+ U) {7 Y; g) L( G' T# T% [, m; ~# Q( ^# `3 H! i) S9 G
在字典树上计算最终最大的异或值
7 p% I4 M$ X4 v. t" @/ b0 C. @) H' V9 O
代码展示3 _  C/ f$ z( \  f6 ~* x& f
# s, z+ }# C0 n& b. I$ \
class Trie {
4 b% k; c( L! y9 _" R& R9 ^8 w( G    Trie left;      // 1/ C. L  a+ c& E5 W9 I
    Trie right;     // 0% o- z8 O! @7 v# x2 z
    int[] count = new int[2];
' F& T! \4 l) w8 Z' t; x    public Trie() {}: u# a4 _% c0 O) `5 m

6 n- P* p: [( Y  u5 e1 g7 e    // s == 1 添加, s == -1 删除9 P* X4 w. @8 w& T- `# h  X% l1 E
    public void insert(int val, int s) {3 n% E: T: p2 j+ S0 Z* E
        int flag = (1 << 30);! _, K- Q# m& I8 F- Q
        Trie node = this;2 g* |# }  I7 `: z6 @4 u( X7 H
        while (flag > 0) {) U: r/ [, r& _/ v# @: p% `
            int bit = (flag & val);
/ r; ?$ d- t9 b9 x  `, I            if (bit > 0) {
2 S$ U( B! K+ ^                // 1 走左边
4 g* Y7 a" u, z' y6 w: T: K                if (node.left == null) {0 K! X- W% |- C5 J; M
                    node.left = new Trie();
9 v6 Z$ a! ^7 ^2 O% V3 N                }3 H! r4 `/ r( w5 R" Q
                node.count[1] += s;( w6 B  ^2 b- P5 B% M
                node = node.left;
: R0 ?, d  U" Y0 E: d% [            } else {' A, |) {! u3 }9 F; g, ]) e& Q# l
                // 0 走右边8 v2 \( e4 D! K6 a0 E
                if (node.right == null) {' A4 K# i/ y8 D0 e6 M& V% T
                    node.right = new Trie();
2 q% l- _1 G" H# T& d                }
( M( K, @. R- z: n4 a- C, h1 [! X                node.count[0] += s;
7 }& F4 X/ B* f: m8 m# n                node = node.right;1 [' v2 C' [2 x, i7 M
            }2 M, V- I0 P. j8 g. K
            flag >>>= 1;
( r6 B  s+ L6 V( C# p4 F        }
6 U3 q" D( G6 \" O( F# Q    }2 O$ P+ a: q- H' K& t! z
" m% }7 I) `  J% n5 D7 I
    public int getMax(int val) {
) F0 B$ t/ C7 Z% G9 E, U        Trie node = this;
5 D. `4 E& J( ?" F9 G3 C( g( U        int flag = (1 << 30);8 E3 @1 |% B+ P6 m  P
        int res = 0;
4 S* I6 c. r  I4 `# i0 e6 M' w. c        while (flag > 0) {; I3 Y0 L, e9 I
            int bit = (flag & val);
7 l- U2 N2 l' d4 \4 T/ _6 f( G            // 贪心算法,1 的话走右边,0 的话走左边
4 o+ I$ ]1 Q: `, b            if (bit > 0) {1 \$ [9 C/ |/ s3 U9 H
                // 走右边,右边不行走左边
$ S1 P" [+ N4 f5 P  `                if (node.right != null && node.count[0] > 0 ) {
) L% R% p) e8 ]' o2 k2 O% a1 w                    node = node.right;7 c0 C  j  W8 _6 K8 b
                    res |= flag;" Y  v' E( q/ }% a$ K9 |' t
                } else if (node.left != null && node.count[1] > 0) {
+ |# I5 u/ x8 q3 L: R0 }                    node = node.left;
  d# N+ f4 `7 i" H& j* {8 Q3 O% C                } else {
6 J/ S9 c; F# ]! i+ f1 R- a. B                    return -1;
( U. p4 u" X# w/ L                }8 y' L: Y% X+ U$ }6 O; ~3 z* [! @
            } else {! j% X* d; B; w8 k! b/ t4 v5 u
                // 优先走左边7 v* H& o6 H+ U
                if (node.left != null && node.count[1] > 0) {
' Q! L+ F( a! f# G5 w* ^+ y, v: E                    node = node.left;1 y! g- F) I) l
                    res |= flag;( Q/ j0 |! O% a8 }* H
                } else if (node.right != null && node.count[0] > 0) {/ Z& t! r# K; j0 p
                    node = node.right;9 W6 C, c' E7 a- d; j9 x
                } else {) v6 q4 K0 U) ]# l  Q0 S
                    return -1;
1 _+ j" P( a- b7 S- ?% e                }4 D; {! f8 c3 v" Y8 Z
            }
% Y' v8 `; `& {, g) U+ d5 D            flag >>>= 1;
  R: L$ T3 d! w! H2 I        }# S. R" t- }  D, q* ^% L/ ^3 |) h
        return res;& K* N; x' D+ F6 m- ~
    }; B- S0 ?8 @( |
}
& `+ x  C+ ]9 }  z- a( X2 ]public class Solution2 {
, I9 G3 n- I% ^; r+ B5 D+ }) [    static class TreeNode {
4 \# |) d/ s. X4 k! h+ i/ P        List<TreeNode> son = new ArrayList<>();
# p( Z' P" g$ O        int val;
, ?8 u6 o& `$ l4 W9 `# }2 `& q        public TreeNode(int val) {
; h! l/ H$ q$ f2 t/ ]4 F% ~; \1 }            this.val = val;. W6 W1 q' d+ C- ?$ z+ x4 \
        }& R5 \1 \0 D1 u
    }$ P9 t" f! ^% y1 I
    Map<Integer, List<int[]>> map = new HashMap<>();
# J: }1 Q6 C6 y9 M& S7 F    Trie trie;  D8 {; y7 W- R# j
    public int[] maxGeneticDifference(int[] parents, int[][] queries) {
( o- J8 O+ M: d/ ~1 j        int n = parents.length, m = queries.length;5 X: Y' B& R% x+ h3 V7 {
        // 封装查询的信息
2 }7 z3 _" r  A3 I  B        for (int i = 0; i < m; i++) {: J- B/ u0 i( D+ p
            int node = queries[i][0], val = queries[i][1];
1 `9 {6 c2 ?3 J+ T            if (!map.containsKey(node)) {
6 c2 `  m1 L' D+ c2 S- D6 l                map.put(node, new ArrayList<>());
! R; [3 s3 V  W8 ]            }
# @& J: v/ [" {1 K            map.get(node).add(new int[]{val, i});
$ Y0 G2 Q- z* M# n0 @. e2 z        }7 m! y. e8 s" v, f. [
        Map<Integer, TreeNode> nodeMap = new HashMap<>();
7 \% C+ }: J. z" l* u        // 构建树
0 m7 ?$ l; d; U: l5 ^" @) X        TreeNode root = null;7 N7 L# z" y! T! i
        for (int i = 0; i < parents.length; i++) {
) I/ O6 t* u% |& [! G: w# y            int p = parents[i];
& s8 ]3 K/ u' f5 T3 z4 p8 q7 U            if (!nodeMap.containsKey(i)) {: Q0 _- y) W6 w# z4 r5 ?) g
                nodeMap.put(i, new TreeNode(i));
; E! C& G% X' r; r! b            }; N6 l" `! \6 s$ q3 i* V8 V
            if (p != -1) {( Q5 w( L) M( r" P- d! P& z9 ]3 X
                if (!nodeMap.containsKey(p)) {
  I5 o" O5 z! N" R5 a: S. e$ v* R                    nodeMap.put(p, new TreeNode(p));7 b7 S/ Z% J5 [  A
                }
3 B+ ?. y, p; t, ^6 S                nodeMap.get(p).son.add(nodeMap.get(i));
/ A) i8 [3 \# ?" l1 w2 }/ o% r            } else {
: G2 M% e  Y1 p. v) e4 F                root = nodeMap.get(i);
8 f7 c4 g* Y: q2 g: [            }
3 t! s  i  Z3 j& H1 o6 C, F        }; g: x6 s6 i- h& A; b; M. z
        trie = new Trie();  O7 R8 y& y% N
        int[] res = new int[m];
1 p5 ?6 i' Y) q8 Q# F! z        // 在树上进行DFS' j5 S/ H: s7 J6 O0 ]$ p# k. ?
        dfs(root, res, map, trie);
( g% @3 t. j% t& w        return res;
5 w! x9 r4 x2 z- ]9 ]
2 [! N4 X+ j9 M3 t1 w+ J: h5 z. D    }1 b) r* n/ [. G' o" I1 R
. b) Z" M6 W$ r' \) \; f& a
    private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {
3 [. |9 J" ~) f        if (root == null) {
% X* L7 d& B' _8 Z0 e- c, Y+ x            return;
) Z- t' ]+ O6 |. Z1 u        }. \* X7 o: I$ G% G* K
        t.insert(root.val, 1);
& N' }0 d( R4 j        if (map.containsKey(root.val)) {* w: W2 e1 \( V/ h5 U$ v- A4 B
            for (int[] each : map.get(root.val)) {
3 m) l% k( r, i" u2 _                int idx = each[1], v = each[0];/ U* \  R9 x4 i/ b
                res[idx] = t.getMax(v);
' k' \8 s5 i! c7 C            }9 v* s2 t$ s+ @* O
        }
/ P( C: V5 C: y. T4 `        for (TreeNode s : root.son) {
/ o, r& w# Q( L7 R. Q. v% v9 F8 c6 Q0 p            dfs(s, res, map, t);0 U7 j2 Y* h! N0 q8 p, G: N1 m
        }
" a: J& Q& ~( ]! h6 p        // delete
1 ]- V* W* \6 @" N, ]+ r6 k1 y        t.insert(root.val, -1);4 O/ }: R  I" l. B
    }
8 i9 t* K9 b$ j0 W( w, S3 h: S0 A}: v$ G2 B+ S0 O' W

- C$ [0 V7 Z2 V" o5 O% z
- {. `3 u# Z1 z* k2 \( A/ L
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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