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

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

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

UWCSSA提醒您:

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

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

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

登录后可回复主题

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

x
关注我们:杭州上岸算法网络科技有限公司
( Q. p6 s) Z9 P2 N, b+ K; T【 NO.1 可以输入的最大单词数】, O5 S* {2 `1 E7 [

8 {1 b; U- n" ]. K; N$ c解题思路
: v# ^) ]" H9 ]; p3 l签到题,循环遍历判断即可。
- d9 m; p" z& d" @6 G  [3 u, L+ `, G7 [9 [* y8 E# I1 a/ v$ k* ^
代码展示
  L9 b3 w& B/ ~/ o0 i5 o0 e% x! Q' P; L4 y1 Y& c% P
class Solution {
7 q4 n5 u: |. S8 i& _3 x    public int canBeTypedWords(String text, String brokenLetters) {6 N: Y8 f' C1 y" s: M
        if (text == null || text.length() == 0) {" N0 I- M3 u# U2 f/ Z: I) g
             return 0;' z8 M0 E  I+ y1 d) ?  c8 u; c
        }
: d; A7 J3 n- G' V/ C& }: S+ I7 Z        String[] texts = text.split(" ");
& B) [  v5 c& J        Set<Character> set = new HashSet<>();8 ^8 _9 R) T  u" K
        for (char c : brokenLetters.toCharArray()) {
8 d& Q* Q  r) u1 \7 H9 y            set.add(c);# ^  e* \: J. X7 p0 v: N
        }
4 `3 K4 J4 `3 m/ F8 P* @& \) i/ ]        int ans = 0, flag = 0;
9 E3 r9 D$ X9 k        for (String word : texts) {
: C2 ?# h% x) S" F# b$ L/ v4 N            for (char c : word.toCharArray()) {
5 {2 @8 h' W: ~) Q/ K( [! C) f                if (set.contains(c)) {: M- T1 o) ~4 Q5 b  t1 \6 j' r
                    flag = 1;
# a; M' d/ n/ k7 ^                    break;: w5 j9 p' ~0 n4 }3 m1 I7 h
                }2 V/ u- ~- W) z: o8 C  k
            }% l; B: l$ \% K/ C% W
            if (flag == 0) {
( E0 Q" R$ }& |. \* T$ G                ans++;2 f3 S, v2 d* b+ H1 a- ~! T  D
            }% j0 V6 P) [5 \' L' ^4 c
            flag = 0;
* t' f. E; L( Z6 H# b& L            4 o. ?- j( s4 N6 d0 X2 n/ ^$ a( x: u! `6 g
        }
; A# t- I; U. R# {: z        return ans;. f% Q( r# P9 r; U% L6 j
    }5 ^" @: C# s. y) B# I3 ]
}
  `: |1 X# f+ Z5 r5 O
1 m) {( s6 w) w5 W: v【 NO.2 新增的最少台阶数】
* u3 @" B- F& O. \# E9 o% s' e% i7 c" u3 I2 n- p. G7 L4 n+ J
解题思路
) l& h" \( s* z/ O" l! P9 f0 j第二道签到题,两两计算差值,需要判断一下是否可以整除。" g7 ~1 _$ x/ k. A6 A: j3 y) f
! \2 q) n7 F- ?$ E  t' H
代码展示! l, v. T  W0 p0 Q  l

" \; ~$ R9 ]7 {4 ~class Solution {; ~) m& m4 X4 k; }* ^
    public int addRungs(int[] rungs, int dist) {
& H# Z* v# F' }; X) o        if (rungs == null || rungs.length == 0) {( Q! J! |: ]. }
            return 0;
( g5 I7 H: v$ [( e& O        }, T* n+ s% I% |7 \+ I! E
        int ans = 0;
: j+ R  K5 y. c7 b" Z2 M0 P3 B        int preRun = 0;
" l$ T/ g$ O, K) s8 ]9 B& ]' _        for (int rung : rungs) {1 [) k* R5 E  o4 j9 `% }, ?
            int diff = rung - preRun;7 B; V! W+ G1 P9 ^
            // 整除的情况可梯子少一个( U7 C: a$ L1 K+ b9 O. x
            if (diff % dist == 0) {) l1 H. Z* Z1 X/ ~3 |
                ans += diff / dist - 1;
1 \9 K/ Q" V  |$ B, S8 p  M            }
* U8 m/ @" \* v            else {3 N8 j: L) h7 K) G% X2 N5 _6 F- g
                ans += diff / dist;5 ^  z. H# k! B; k7 ~% D
            }
) n7 b- _& `9 S7 p1 t            preRun = rung;
4 q/ }- p8 V9 b& E        }  J+ E) Z4 N. Q' W
        return ans;) ]+ d2 I* w. e. a4 N: ?; w
    }* C5 A+ O% s; |3 t( R
}( F( t7 A0 Q$ C' P  Y
: V9 f* Z8 M5 T
: w/ [* ~! c+ H' T
【 NO.3 扣分后的最大得分】/ V, ^0 }  w* _& |  ~. B
# ?- _9 ^3 Y- N# @, J" M' g
解题思路5 i% B& d3 N3 e  c/ ]* F: ]
坐标型动态规划
: A+ r# Y1 e- T; I# {6 |8 i
& _4 `1 S$ V& S) h9 S; Udp[i][j]表示处于坐标 i j 的位置的最大收益
( q* _* H- ?0 k7 P$ i
& I( M2 x& k7 u) z# V, v普通的坐标转化会超时
3 b, j( X; ]5 u& q0 @
  u+ ]# T6 I4 h( m: k8 c2 v- l考虑针对每一个j,会从 j的左侧和右侧转移过来,我们只想要一个收益最大的
8 Q( I, v' @& j8 G
# K5 z2 H6 H" M: n+ {* U因此在遍历 j 的时候记录这个左侧和右侧最大的收益,给下一层用4 K) F+ j' N, o1 P' B

+ T2 B7 R( R: c" E# ^还有优化的空间,i 可以压缩成两行
* m5 x0 K! [  w! \; X( L/ [
3 k3 f# a- {7 t6 g5 g代码展示2 Y  b; P$ {% a5 {5 g
, j$ E+ A7 V& I& Z! g4 n$ c6 _0 A
class Solution {
' l9 i' z( N; G    public long maxPoints(int[][] points) {
  P3 L- |; J8 }" p        if (points == null || points.length == 0 || points[0].length == 0) {. q1 E. B) t/ w0 v) r6 F$ e
            return 0;
7 N3 b8 p% V' U        }8 D% f, ~/ ]. A" S3 D. e% v* Q
        int n = points.length;+ K9 Z0 D* h2 j$ e' Q4 @
        int m = points[0].length;+ j0 V3 G: b4 s+ e) i
        long[][] dp = new long[n][m];. d/ z/ x; m4 F
        // 首行初始化2 R. J. j% ]7 I. F0 G
        for (int j = 0; j < m; j++) {
+ B! U* k+ X, i! p& a& ^- H            dp[0][j] = points[0][j];- F5 Y  u6 G* T4 ~7 r6 Z  F4 H
        }
% I) {, l$ ?3 m6 v/ e  K        for (int i = 1; i < n; i++) {+ \2 H* g- [7 z% p4 T& K7 u  T' s
            // 对于所有上一行左边的数,都是加上它的坐标减去自己的坐标;: Q8 I' E, c. n
            // 对于上一行所有右边的数,都是减去它的坐标加上自己的坐标;
5 O" a& A' N0 ?2 r            long leftMax = Integer.MIN_VALUE;
% g4 Q; o3 d$ x7 p* G/ y. P            long rightMax = Integer.MIN_VALUE;. E7 k3 S7 q4 n' O# x
            for (int j = 0; j < m; j++) {
) ~/ C/ ]1 h/ W                leftMax = Math.max(leftMax, dp[i - 1][j] + j);
, h  H) [& e0 B: p% g                rightMax = Math.max(rightMax, dp[i - 1][m - 1 - j] - (m - 1 - j));
8 ]7 ]2 S' i$ j+ A( s, s8 O                dp[i][j] = Math.max(dp[i][j], points[i][j] + leftMax - j);: ~4 G, e- J  V- h
                dp[i][m - 1 - j] = Math.max(dp[i][m - 1 - j], points[i][m - 1 - j] + rightMax + m - 1 - j);8 `  X5 H: f4 O$ ~! e9 v/ g% q  a! J
            }% _; m3 a5 K! B3 h' X8 t
        }" A/ a9 j* K9 A6 @# H/ G( R
        long ans = 0;- e  e7 h$ o+ x6 _: M; C; y
        for (int j = 0; j < m; j++) {3 v8 O" Q6 }- W# f0 l4 O
            ans = Math.max(ans, dp[n - 1][j]);
: z' I0 w' g" y0 H        }
9 c, _8 {- r& y+ i: G* v! ?        return ans;
, B- T! M4 f6 p* Q    }" _' D0 f: d3 k2 ^' o3 z  i
}
, g( ]4 s' q/ O3 J
! h' k0 }" v' S6 ^. t9 [! _* O) i6 `+ a( I. C
【 NO.4 查询最大基因差】7 b4 p3 L, W" Z) K. G' U& N7 [+ K, D& S
3 q  g& v* P, n; ~: y
解题思路7 {! R( \: g* N% G5 o
二进制的字典树:将数字转化成二进制记录在字典树当中1 b" M9 w$ l9 h
5 m1 ]/ }  Q9 z" P: S( ^' ^6 ]/ T
构建树,方便做DFS
: A) Q/ O, C8 B  G  C4 U2 |6 p, n, e1 h
每搜索一个数字,将该数字更新到字典树当中
8 ~9 s: l* n8 ^4 J/ a+ I  U
$ M5 s# d1 j) T在字典树上计算最终最大的异或值* ]- J; |# R# C/ v* W" `- ]% ~
& r6 J0 k' m, X0 `9 w8 I, P2 Y9 I
代码展示( J1 R- ?: I! k4 k
+ P/ N9 q% w3 J$ y; W# F! X
class Trie {
: w* G1 Z+ v1 \- [    Trie left;      // 1* K2 w0 @- H0 s) m* U0 L6 H4 o
    Trie right;     // 0
! e% Q( h0 ~% Q  F    int[] count = new int[2];
; k4 `8 Q3 @3 ^3 @/ E+ \( Z    public Trie() {}
% Q; N- O" }: H% d: U# @0 r5 n# p9 q$ J) q
    // s == 1 添加, s == -1 删除) Q4 `/ t( R6 L* n- E+ J; o! ?
    public void insert(int val, int s) {
5 R, G2 P6 f* d5 v' Y& [        int flag = (1 << 30);
: u' j* Y$ w  S+ N        Trie node = this;
, X# b. l8 u  j# V* d# T! f; C        while (flag > 0) {' Y3 b# Z8 s0 Y7 M5 n+ p, D
            int bit = (flag & val);5 s3 o1 {' w7 U4 V0 j' d5 P
            if (bit > 0) {
8 s7 }& F. p; A+ C! o  i: k7 W                // 1 走左边
# B7 Y$ G/ K" h! `% a" ?                if (node.left == null) {
& ?+ r3 N; E! J" H- F: b                    node.left = new Trie();
  L) K& }& u# |* d4 ^8 b- C7 P7 _                }" O. J+ k! O3 x0 R5 m$ K
                node.count[1] += s;, O( X7 \& A. s2 g3 E1 H
                node = node.left;
' k2 E  Y+ i6 r0 H# ~+ ?! `            } else {
6 f( v# @" ~* z" x- T  d) s3 \                // 0 走右边+ O. N; O7 o. W+ Y: y
                if (node.right == null) {
* P# o1 }0 o2 I1 w* e- v1 y                    node.right = new Trie();3 S1 Y% p$ V) e  M' y
                }
, n1 W8 I# M( x$ m& H: R                node.count[0] += s;$ K& K: j5 b8 X' f2 y
                node = node.right;
7 U# S3 m0 ]& C0 F  D/ f            }' u1 S$ U% o) c& M
            flag >>>= 1;) i' q) {; j( L, }
        }
, u% O- e! V4 p( w4 ?# B    }7 K% J5 _6 S3 v! X

9 O* W  a. f' u2 {; Z& ^/ F; k    public int getMax(int val) {
. Q0 N2 x3 `1 R; H" c; j        Trie node = this;1 k) r3 V/ _" K" q
        int flag = (1 << 30);
0 _. \2 l/ d; Q2 B        int res = 0;
$ F, K2 i9 ]/ L( @        while (flag > 0) {
2 l- M5 G4 d; q4 b0 I            int bit = (flag & val);; x8 L% u% j2 b5 k+ Z- W
            // 贪心算法,1 的话走右边,0 的话走左边
9 Z7 N& D5 H9 U* z            if (bit > 0) {& w  k; P8 g0 t* L8 c
                // 走右边,右边不行走左边  {- I2 ~1 ?' _+ W$ ]
                if (node.right != null && node.count[0] > 0 ) {
# i3 v5 f+ G/ \  E5 v+ J! \                    node = node.right;+ E0 q, n1 Y/ u- Q- r. w3 C
                    res |= flag;' S% Z; U2 v8 x+ R* H3 y
                } else if (node.left != null && node.count[1] > 0) {2 G! O  }; |3 H* `8 L1 i: T
                    node = node.left;; v7 U: P  P5 x
                } else {
& r/ e4 \$ K6 H: H% }                    return -1;
' t7 X* Y. s& }% v2 X' I" O                }
! I4 C& k" t+ p2 j# Y            } else {
3 n# i1 k7 j" p* I% f# j$ m" i. j                // 优先走左边8 b  a+ p1 o, T  y: ~
                if (node.left != null && node.count[1] > 0) {& M( `5 K* e2 g7 m9 t2 F6 [
                    node = node.left;
0 H& H5 J5 F: ]                    res |= flag;
" v+ W0 I' o. w- P" p1 k' N                } else if (node.right != null && node.count[0] > 0) {1 a) u" E( ~; t# d5 }' F4 n- M
                    node = node.right;
! J1 h4 W6 s5 R                } else {; ]/ h( H, [, Z
                    return -1;9 Z$ A8 [) l% M  g6 x8 |
                }9 T% c3 C3 V4 ]
            }
( x1 w* Y. R  l            flag >>>= 1;
( T$ {$ j" S+ @6 U- \. k  O        }1 V9 O6 d8 _/ \% \  |* R2 A" z6 X, P
        return res;
( W3 e+ h5 ~1 F8 i6 N    }- A+ `# Z/ c: r  k2 g5 @/ S& J8 a
}
* S4 D3 ~2 B% Z$ U# W) i! H) hpublic class Solution2 {! p: }# z: Y4 C7 z$ Z
    static class TreeNode {
3 V! Z. N/ E1 \% b+ ?        List<TreeNode> son = new ArrayList<>();
. r) `- m) G$ \, G& y        int val;
% b/ \) R- G# _' `! O        public TreeNode(int val) {
9 }- U# w/ j; W- I$ E5 I            this.val = val;# ]3 X3 J: j: m2 @* X, f* j
        }" w. X! A) t+ J) I2 b+ {; J
    }
7 y- E% S* s9 {/ A    Map<Integer, List<int[]>> map = new HashMap<>();
6 e7 h% g6 _  g    Trie trie;
" t6 O, P. `2 E    public int[] maxGeneticDifference(int[] parents, int[][] queries) {+ {  z3 ?/ L. v1 w0 m& o/ C
        int n = parents.length, m = queries.length;
  o/ q; y9 m. d( ^7 r* q$ v        // 封装查询的信息( o1 m/ g) t  F7 u3 E- s/ D9 P4 n
        for (int i = 0; i < m; i++) {) {. ^6 B' x% q7 _- R
            int node = queries[i][0], val = queries[i][1];! }5 q) L* n; x/ R/ ~( u
            if (!map.containsKey(node)) {
! b  }4 x* h7 B2 g* d                map.put(node, new ArrayList<>());, z( `2 y( O! [
            }2 s3 e' w7 h/ x" X* z
            map.get(node).add(new int[]{val, i});
: z0 R4 T9 J& X9 ?        }7 V! p$ k+ b. n* [7 D" |
        Map<Integer, TreeNode> nodeMap = new HashMap<>();) o$ ]. U: G) J% m- g
        // 构建树/ P8 g3 k, {' M4 p$ H
        TreeNode root = null;
5 J9 @1 K; l5 Y( [        for (int i = 0; i < parents.length; i++) {  M: @( H6 A) ]5 i# g6 p
            int p = parents[i];
$ ]& u. ~( N. q6 r6 B            if (!nodeMap.containsKey(i)) {
" J/ e+ ~! F4 e% R2 e% k                nodeMap.put(i, new TreeNode(i));
4 O, K" X; d  G2 a3 W: P9 K            }% b3 L- N$ e4 I( L0 q3 b, n5 r5 G
            if (p != -1) {- t5 u2 l8 i- W
                if (!nodeMap.containsKey(p)) {
) T8 C! M' p* j2 ?                    nodeMap.put(p, new TreeNode(p));
0 P: ~4 r- ^5 C                }
" u! f" Y9 C) Q+ `, _, u. m+ L                nodeMap.get(p).son.add(nodeMap.get(i));
. |' N/ z& H* n, w# |            } else {$ w2 y& N- A  |/ Z' w3 }
                root = nodeMap.get(i);
& J. j* P0 ~$ e6 Y4 {8 F3 B            }
2 Y% p/ Z5 x! t9 `7 L" |! J  H8 _. C        }, y, A) F6 w  m  ?3 m4 v- y8 m- Z
        trie = new Trie();2 w: E+ x/ Z7 m/ f
        int[] res = new int[m];9 G. Q& d8 w% l3 Q
        // 在树上进行DFS+ y- s* ~, t: A
        dfs(root, res, map, trie);4 |( }+ ?9 R. S2 l
        return res;
; W! M. P2 I7 ~7 Z- k3 V
3 G: ]1 W$ O8 K0 c1 {/ v2 W5 ?    }3 @; }7 E4 S, y( P7 K* x6 B2 ?% p

' x, q8 F8 _0 L( H" s/ u5 D    private void dfs(TreeNode root, int[] res, Map<Integer, List<int[]>> map, Trie t) {5 |  x1 @9 s: S1 u: R
        if (root == null) {
' b2 r4 l2 O8 b0 A1 {            return;
' M9 g* S- C( d: @  D# P7 L        }
  `/ N+ C/ F8 R        t.insert(root.val, 1);
, \2 A" T$ v7 P; X        if (map.containsKey(root.val)) {8 J. R. w( i; m3 h* C& `6 Z
            for (int[] each : map.get(root.val)) {
* D0 p  f! F  q3 F6 W! V; W                int idx = each[1], v = each[0];
8 S2 O5 j: q: K                res[idx] = t.getMax(v);; z% \( v) p& S
            }
: n7 O/ ]  K5 ?) p0 s) n        }& s2 r' C6 X: V' V/ U  [# R- k
        for (TreeNode s : root.son) {% Q% o9 P0 X1 Q. Q9 M% y" J
            dfs(s, res, map, t);
; e( B9 _( \+ [5 C. P2 r$ a  x        }
2 \. C7 C& m0 a' i/ a/ ~- J        // delete$ J5 P: N7 c  i* [! }
        t.insert(root.val, -1);, e6 ~2 z4 a/ f1 r1 J  P' E0 g8 k
    }
4 m6 |* {( N$ i9 Y0 p}3 C+ s$ q" ^% `+ Z: D
$ ?4 Q( }5 C8 w4 d! q" }
1 A/ \& v* n  z1 Y& w& ^
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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