No.1 检查二进制字符串字段2 ]2 E+ z1 Z4 \
# T: u4 j. N$ N2 F) U2 l6 a$ @+ ]解题思路 d8 L0 i' _* B, l: }9 _' g0 f# |2 k
: v. Q2 G) q# T符合要求的字符串即前缀全是 1,后缀全是 0 的字符串。% |$ U- g+ G! z! \0 ^
' [6 y( k, r! J
代码展示
& Z" [9 p5 O. \- D) ~+ L' ]- D- a/ |3 ?& t+ h/ M* m- Y" J
- class Solution {
! i2 m0 w. \; d - public boolean checkOnesSegment(String s) {
8 Q2 \6 o' b Z8 [& D, J - if (!s.contains("0")) { \3 A9 P, `- m6 B# o4 M3 S2 B
- return true;
% J( X, U6 x7 m* t: p - }
, C. K" a, M( J" g - if (s.substring(s.indexOf("0")).contains("1")) {4 a' V& `' o8 l: J! x) D
- return false;
+ v+ L% u& i, H4 U9 O' N - }, Y" K* y% x z
- return true;* w. D/ J4 Y w: Y# d% @* `
- }, K+ P6 |# N% \+ O; D) Y( w
- }
复制代码 , Y) u% l* r. D$ }7 Q) ^2 T1 a
No.2 构成特定和需要添加的最少元素
$ w+ F9 Q. i6 J1 q
/ p1 f$ h* O+ {' {2 T解题思路
* B: I# w5 y, M+ k% P5 u4 Q6 ~% T& ]$ S$ P8 d! j3 V# h7 a
贪心即可,每次都添加绝对值尽可能大的。注意总和可能溢出 int,所以中间运算要使用 long。! H/ k; ~; k. w
+ z( X1 T# U: `( Q3 K" D代码展示* Q; Q f( H, i5 G# P
8 I) L+ A- L& P$ Z* W" v- class Solution { q" K( g: n8 \; p( l* r2 q
- public int minElements(int[] nums, int limit, int goal) {
2 a1 R' q; j, b2 o2 d2 s6 L1 Z* C" [ - long sum = 0;
+ U5 ^+ g; W# e! i5 C/ X - for (int num : nums) {, D) O# p( V8 K- G" |, M
- sum += num;
6 k q) I0 T+ R/ ~3 H+ q# p" B - }
5 f: O; s2 j8 { - sum = Math.abs(goal - sum);
; O( c( t% O& D6 c - int count = (int) (sum / limit);+ u( I- `1 l3 [* d$ N0 a
- if (sum % limit != 0) {
* b1 y/ C f" k& X - count++;0 J- h% ?0 O- m1 A, Z
- }
) B' ?2 ]( N1 _+ }0 f/ N* f3 J - return count;7 i7 F( R8 i6 {
- }0 v- j' Y% U! R/ F7 g% i
- }
复制代码 , h: m5 h* a; e! p
No.3 从第一个节点出发到最后一个节点的受限路径数
! l, q$ G( h4 w) F2 O# ?; ?% p/ W+ I% ^# C0 I" g
解题思路
: X! V3 I3 b( Q7 T C5 b7 N$ G/ T/ p1 S/ F% ~" r/ i+ v# L3 v
Dijkstra + DP
M$ M, X8 @& A( B
! f" P2 E% e6 B# F代码展示, Z4 a; l& D. k1 g3 U8 `
& l7 n$ K2 ?: B) G" F- n- class Solution {
+ t: j/ A1 }% O- I7 b - static class Edge {
: _% }% x6 v( R; Y; \& O - int next;4 ~/ [9 [8 S1 ?# o5 ]" X( }
- int len;8 q. |% Z, [3 z. W! v2 g9 L
) F8 u* H4 O" o! C- Edge(int next, int len) {
4 s3 T' o, A$ s H4 p - this.next = next;
! G5 W0 T: I: o- r$ I2 Z1 Q- d - this.len = len;9 y, o) Y6 c D% U% i ~
- }
+ n- H1 }, }0 R+ c5 c; d7 d - }
# f# C1 ]6 z. [! F" [
: g9 Z$ y: O! P* F- public int countRestrictedPaths(int n, int[][] edges) {8 A5 F: B! c0 d8 w- p( @
- // 建图
3 g/ l) z% Z+ J! F - Map<Integer, List<Edge>> graph = new HashMap<>();
! U# W8 {/ T+ {) J& q1 B; } - for (int[] edge : edges) {: g. R& Q6 ~0 x6 @
- for (int i = 0; i < 2; i++) {0 R( O- L J5 s5 E
- if (!graph.containsKey(edge<i>)) {: m/ d4 U( o6 r2 j6 O6 i
- graph.put(edge<i>, new ArrayList<>());
4 ~( w* ~' r$ s8 n& R% `% K - }
# p9 R6 |9 b. A - graph.get(edge<i>).add(new Edge(edge[1 - i], edge[2]));
$ o7 C p1 j6 X7 O f - }
% g; v, M' _# l1 {. } _& h% g - }! ~+ ~) t, W6 d8 B: n: ~" Z' B
- // dijkstra 求出 distanceToLastNode
h& Y% h3 W6 q% X - var distanceToLastNode = dijkstra(n, graph);- {- ^% ?" f, X6 {- K8 T, s# o4 J
- // DP- j$ b. U7 E! U5 Y- ^( R: }: D
- int[] mem = new int[n + 1];2 G+ M \6 I( W/ O: T
- Arrays.fill(mem, -1);( B5 z1 k3 a& e) {- k
- mem[n] = 1;) C3 ]2 P" K4 U
- return dp(1, mem, distanceToLastNode, graph);! y4 C. E9 I; X6 l
- }
* M$ z1 m% c5 g: L8 \" Z, f0 N - : n6 c7 @7 q6 L
- private int dp(int cur, int[] mem, Map<Integer, Integer> distanceToLastNode, Map<Integer, List<Edge>> graph) {- ^# u, W1 D& `! P& H: c
- if (mem[cur] >= 0) {/ V9 b. h) }) p2 ]/ Q4 j$ i
- return mem[cur];
# i9 Z! ^" A+ \6 ~* { - } `* n5 f# C& c2 _2 ]
- mem[cur] = 0;- n1 B. d( g) U: t
- for (var next : graph.get(cur)) {
. n# [. L4 `! X# y, Y4 q3 t! n1 ? - if (distanceToLastNode.get(cur) > distanceToLastNode.get(next.next)) {: |. G) K& g( s( Q- m
- mem[cur] = (mem[cur] + dp(next.next, mem, distanceToLastNode, graph)) % 1000000007;
$ s3 H+ B0 i0 Q( ]; f. I2 Y( i) U - }
7 J3 Q9 z2 j6 A) i+ T2 t' s3 q6 { U - }; I$ N9 `$ c) B& t7 P
- return mem[cur];# s: W3 O* ]0 Y. G2 k1 `
- }
' T1 K% V7 A$ V, N) W - ' }1 o( n+ q- L# e# J
- static class Node {
6 e8 B/ H9 Z9 d; H) Q. p - int to;6 u7 ]! l: Y" T ?; w/ N
- int len;+ A9 a1 `3 F+ w. \; \4 [
- 3 T# {1 q- G! d
- Node(int to, int len) {
) u! N, X2 W* ], e) g7 ]* r - Look @t This To... = to;
# {( L% j# k# Q0 E - this.len = len;& S. _9 e/ r, s
- }: u( t+ K, Y- s3 }% x& Y' i' P
- }
& h& b+ F$ O, k' q9 I7 q- T. [ - " C: i6 {6 u- P: L2 A
- private Map<Integer, Integer> dijkstra(int start, Map<Integer, List<Edge>> graph) { {5 M8 M" u1 p6 V
- Set<Integer> visited = new HashSet<>();
" C0 q) U( u! v! D+ I - Map<Integer, Integer> res = new HashMap<>();4 T7 _ w. I4 f) L6 \- T3 ~
- PriorityQueue<Node> heap = new PriorityQueue<>((o1, o2) -> (o1.len - o2.len));
2 n$ Z9 j. r* _ - res.put(start, 0);' e2 f8 F$ _' E, o+ m
- heap.add(new Node(start, 0));& y3 u4 R A% c% B
- while (!heap.isEmpty()) {
6 |, P4 B/ }) m7 w - Node node = heap.poll();
+ V: z0 V5 U% e - if (visited.contains(node.to)) {7 y3 b m4 m* }$ d' M8 V0 |/ u0 }' _
- continue;
% M( ?2 T8 i: F% O; c - }
. {. I2 ?' o& ? - visited.add(node.to);
8 k# V2 ^ \4 l) _$ v( e - for (Edge e : graph.get(node.to)) {6 z) E6 Q) f# y% v6 w8 O
- if (res.getOrDefault(e.next, Integer.MAX_VALUE) > node.len + e.len) {
8 e! e9 n3 _! c1 i' \1 O8 K7 q - res.put(e.next, node.len + e.len);+ [$ W+ N8 N7 y b8 d
- heap.add(new Node(e.next, node.len + e.len));
5 x2 a! R9 [( S" I - }
1 [4 M1 }. Q- K - }) @5 i! @2 X1 W/ i/ u
- }/ I8 ]6 l2 b+ E6 g' i; M$ x9 [. {
- return res;
5 n8 }! X+ L* Y3 `" K2 A - }4 A2 D( N0 @/ f+ `
- }</i></i></i>
复制代码 ' g% L* g& \( P
- t p- A! U9 v$ P- H
No.4 使所有区间的异或结果为零
* |8 n7 E, g! G7 K7 j( t& p/ R/ V9 w1 x( D) u+ \/ n7 S
解题思路! C; @/ e( ]' f7 R2 h1 \5 }: x S& r
8 r+ q+ r) W4 G7 d- {
DP5 Y$ t+ B6 S3 R+ k: ~
( J- u9 ?* l( ~+ V8 C0 U
代码展示
/ u: q8 r' ?( n# u e$ O
$ {& c9 X' N. M, X7 M- class Solution {" L5 @: E- C8 \
- public int minChanges(int[] nums, int k) {
) n/ F3 h& g3 I! y - // count[j] 表示在每个长度为 k 的子区间的第 i 个位置上,数字 j 出现了多少次/ N1 j( y" H% I1 V1 B" [5 w; b
- int[][] count = new int[k][1 << 10];
( a& B4 @/ V! W) [0 F - for (int i = 0; i < nums.length; i++) {
( `3 ]8 B$ w. t5 _/ H$ R( @6 {$ D6 ? - count[i % k][nums]++;
( `! D! a" i* C* `2 V) }. G( v1 @ - }; C8 h) y) D/ w- H1 \- B4 z- z
- - `7 ?/ K; o( P, z
- // dp 表示将每个子区间的前 i 个位置变成一致的至少要改变多少个数字- x3 E% ~2 W" z# }$ F
- int[][] dp = new int[k + 1][1 << 10];' t& c$ D6 ~% c+ }
- for (int i = 0; i <= k; i++) {" R J( B6 R. }( J/ y/ Z
- Arrays.fill(dp, nums.length);' g# U3 ^, q8 U0 `/ d, u i
- }
; m; p( u6 t; W$ M - dp[0][0] = 0;0 B* _8 Z* p. ]8 K: E; I. t
6 R& l& v5 M% b" ?7 F# q5 Q- ~; k- int min = nums.length, sum = 0;; K. P. Q0 p# a7 h k) z
- for (int i = 1; i <= k; i++) {
, H6 O2 ^% z& A" |* V - int[] cur = count[i - 1];& q' l5 z" _# l' s: [
- int tot = 0, max = 0;: F$ c z- e) C$ w
- for (int j : cur) {
: \, y& I4 H+ f& | - tot += j;' b& l7 e7 m, z' t% B) q5 Y
- max = Math.max(max, j);
" _: ~) y- e* ^ - }
# h0 r5 j% e3 A) f - sum += tot - max;
) a5 s8 g4 U! |) B/ f' n - min = Math.min(min, max);6 V; X* r- v% Z7 z" F
- for (int j = 0; j < (1 << 10); j++)9 O& N- V$ ?7 @0 b6 |0 b
- if (cur[j] > 0) {
. P% H8 ?- N( W6 _9 F5 h - int now = tot - cur[j];; b' c3 `- ~& h" _
- for (int K = 0; K < (1 << 10); K++)$ v/ }' y: s% J- Q# |
- dp[j ^ K] = Math.min(dp[j ^ K], dp[i - 1][K] + now);
1 l0 U5 K- W( h. h+ r' |( x - }
8 ]& e& a/ k y5 ~1 R8 v - }
' e4 y* j' g, m0 s - return Math.min(dp[k][0], min + sum);
* w" r$ v3 _/ M+ Z - }
/ R/ @+ e0 r5 \/ l$ @9 A2 u/ ]: W6 v/ N - }
复制代码
; h5 _/ {; L3 b# l/ A: b上岸算法由华大学长精心创立,是一家致力于用高质量,高互动性小班课程来帮助学生更好的在就业市场中定位以及求职的公司。我们以顶级的课程质量,高互动性的教学方式以及独特的小班教学模式来帮助学生更快的跨过求职的鸿沟,用最高效,经济,合理的方式帮助更多学生快速找到梦寐以求的工作。
! [# k9 D# w9 {) C' i* {- ?' Y |