modify code

master
algorithmzuo 3 years ago
parent 08026a3cdc
commit 47becb5b25

@ -0,0 +1,136 @@
package class_2022_08_1_week;
import java.util.HashSet;
import java.util.PriorityQueue;
// 在一个 2 * 3 的板上board有 5 块砖瓦,用数字 1~5 来表示,
// 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字上下左右进行交换.
// 最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
// 给出一个谜板的初始状态 board 
// 返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
// 测试链接 : https://leetcode.cn/problems/sliding-puzzle/
public class Code01_SidingPuzzle1 {
public static int b6 = 100000;
public static int b5 = 10000;
public static int b4 = 1000;
public static int b3 = 100;
public static int b2 = 10;
public static int[] nexts = new int[3];
public static int[][] end = { { 1, 2 }, { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 } };
// [1 0 2]
// [3 4 5]
// 102345
public static int slidingPuzzle(int[][] m) {
HashSet<Integer> set = new HashSet<>();
int from = m[0][0] * b6 + m[0][1] * b5 + m[0][2] * b4 + m[1][0] * b3 + m[1][1] * b2 + m[1][2];
PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> (a[0] + a[1]) - (b[0] + b[1]));
// [
// 从from出发到达当前状态已经走了几步
// 从当前状态到最终状态的估计距离
// 当前状态是什么,用数字代表
// ]
heap.add(new int[] { 0, distance(from), from });
int ans = -1;
while (!heap.isEmpty()) {
int[] arr = heap.poll();
int distance = arr[0];
int cur = arr[2];
if (set.contains(cur)) {
continue;
}
if (cur == 123450) {
ans = distance;
break;
}
set.add(cur);
int nextSize = nexts(cur);
for (int i = 0; i < nextSize; i++) {
int next = nexts[i];
if (!set.contains(next)) {
heap.add(new int[] { distance + 1, distance(next), next });
}
}
}
return ans;
}
public static int nexts(int from) {
// 301245
// 10000
// a = 3
int a = from / b6;
// b = 0
int b = (from / b5) % 10;
// c = 1
int c = (from / b4) % 10;
// d = 2
int d = (from / b3) % 10;
// e = 4
int e = (from / b2) % 10;
// f = 5
int f = from % 10;
if (a == 0) {
nexts[0] = from + (b - a) * b6 + (a - b) * b5;
nexts[1] = from + (d - a) * b6 + (a - d) * b3;
return 2;
} else if (b == 0) {
nexts[0] = from + (a - b) * b5 + (b - a) * b6;
nexts[1] = from + (c - b) * b5 + (b - c) * b4;
nexts[2] = from + (e - b) * b5 + (b - e) * b2;
return 3;
} else if (c == 0) {
nexts[0] = from + (b - c) * b4 + (c - b) * b5;
nexts[1] = from + (f - c) * b4 + (c - f);
return 2;
} else if (d == 0) {
nexts[0] = from + (a - d) * b3 + (d - a) * b6;
nexts[1] = from + (e - d) * b3 + (d - e) * b2;
return 2;
} else if (e == 0) {
nexts[0] = from + (b - e) * b2 + (e - b) * b5;
nexts[1] = from + (d - e) * b2 + (e - d) * b3;
nexts[2] = from + (f - e) * b2 + (e - f);
return 3;
} else {
nexts[0] = from + (e - f) + (f - e) * b2;
nexts[1] = from + (c - f) + (f - c) * b4;
return 2;
}
}
// 当前的数num
// 最终要去的数123450
// 返回num -> 123450 曼哈顿距离!
public static int distance(int num) {
int ans = end[num / b6][0] + end[num / b6][1];
ans += end[(num / b5) % 10][0] + Math.abs(end[(num / b5) % 10][1] - 1);
ans += end[(num / b4) % 10][0] + Math.abs(end[(num / b4) % 10][1] - 2);
ans += Math.abs(end[(num / b3) % 10][0] - 1) + end[(num / b3) % 10][1];
ans += Math.abs(end[(num / b2) % 10][0] - 1) + Math.abs(end[(num / b2) % 10][1] - 1);
ans += Math.abs(end[num % 10][0] - 1) + Math.abs(end[num % 10][1] - 2);
return ans;
}
public static void main(String[] args) {
int from = 301245;
int size = nexts(from);
for(int i = 0 ;i < size;i++) {
System.out.println(nexts[i]);
}
int num = 314502;
System.out.println(distance(num));
}
}

@ -0,0 +1,120 @@
package class_2022_08_1_week;
// 在一个 2 * 3 的板上board有 5 块砖瓦,用数字 1~5 来表示,
// 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字上下左右进行交换.
// 最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
// 给出一个谜板的初始状态 board 
// 返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
// 测试链接 : https://leetcode.cn/problems/sliding-puzzle/
public class Code01_SidingPuzzle2 {
public static int[] status = { 12345, 12354, 12435, 12453, 12534, 12543, 13245, 13254, 13425, 13452, 13524, 13542,
14235, 14253, 14325, 14352, 14523, 14532, 15234, 15243, 15324, 15342, 15423, 15432, 21345, 21354, 21435,
21453, 21534, 21543, 23145, 23154, 23415, 23451, 23514, 23541, 24135, 24153, 24315, 24351, 24513, 24531,
25134, 25143, 25314, 25341, 25413, 25431, 31245, 31254, 31425, 31452, 31524, 31542, 32145, 32154, 32415,
32451, 32514, 32541, 34125, 34152, 34215, 34251, 34512, 34521, 35124, 35142, 35214, 35241, 35412, 35421,
41235, 41253, 41325, 41352, 41523, 41532, 42135, 42153, 42315, 42351, 42513, 42531, 43125, 43152, 43215,
43251, 43512, 43521, 45123, 45132, 45213, 45231, 45312, 45321, 51234, 51243, 51324, 51342, 51423, 51432,
52134, 52143, 52314, 52341, 52413, 52431, 53124, 53142, 53214, 53241, 53412, 53421, 54123, 54132, 54213,
54231, 54312, 54321, 102345, 102354, 102435, 102453, 102534, 102543, 103245, 103254, 103425, 103452, 103524,
103542, 104235, 104253, 104325, 104352, 104523, 104532, 105234, 105243, 105324, 105342, 105423, 105432,
120345, 120354, 120435, 120453, 120534, 120543, 123045, 123054, 123405, 123450, 123504, 123540, 124035,
124053, 124305, 124350, 124503, 124530, 125034, 125043, 125304, 125340, 125403, 125430, 130245, 130254,
130425, 130452, 130524, 130542, 132045, 132054, 132405, 132450, 132504, 132540, 134025, 134052, 134205,
134250, 134502, 134520, 135024, 135042, 135204, 135240, 135402, 135420, 140235, 140253, 140325, 140352,
140523, 140532, 142035, 142053, 142305, 142350, 142503, 142530, 143025, 143052, 143205, 143250, 143502,
143520, 145023, 145032, 145203, 145230, 145302, 145320, 150234, 150243, 150324, 150342, 150423, 150432,
152034, 152043, 152304, 152340, 152403, 152430, 153024, 153042, 153204, 153240, 153402, 153420, 154023,
154032, 154203, 154230, 154302, 154320, 201345, 201354, 201435, 201453, 201534, 201543, 203145, 203154,
203415, 203451, 203514, 203541, 204135, 204153, 204315, 204351, 204513, 204531, 205134, 205143, 205314,
205341, 205413, 205431, 210345, 210354, 210435, 210453, 210534, 210543, 213045, 213054, 213405, 213450,
213504, 213540, 214035, 214053, 214305, 214350, 214503, 214530, 215034, 215043, 215304, 215340, 215403,
215430, 230145, 230154, 230415, 230451, 230514, 230541, 231045, 231054, 231405, 231450, 231504, 231540,
234015, 234051, 234105, 234150, 234501, 234510, 235014, 235041, 235104, 235140, 235401, 235410, 240135,
240153, 240315, 240351, 240513, 240531, 241035, 241053, 241305, 241350, 241503, 241530, 243015, 243051,
243105, 243150, 243501, 243510, 245013, 245031, 245103, 245130, 245301, 245310, 250134, 250143, 250314,
250341, 250413, 250431, 251034, 251043, 251304, 251340, 251403, 251430, 253014, 253041, 253104, 253140,
253401, 253410, 254013, 254031, 254103, 254130, 254301, 254310, 301245, 301254, 301425, 301452, 301524,
301542, 302145, 302154, 302415, 302451, 302514, 302541, 304125, 304152, 304215, 304251, 304512, 304521,
305124, 305142, 305214, 305241, 305412, 305421, 310245, 310254, 310425, 310452, 310524, 310542, 312045,
312054, 312405, 312450, 312504, 312540, 314025, 314052, 314205, 314250, 314502, 314520, 315024, 315042,
315204, 315240, 315402, 315420, 320145, 320154, 320415, 320451, 320514, 320541, 321045, 321054, 321405,
321450, 321504, 321540, 324015, 324051, 324105, 324150, 324501, 324510, 325014, 325041, 325104, 325140,
325401, 325410, 340125, 340152, 340215, 340251, 340512, 340521, 341025, 341052, 341205, 341250, 341502,
341520, 342015, 342051, 342105, 342150, 342501, 342510, 345012, 345021, 345102, 345120, 345201, 345210,
350124, 350142, 350214, 350241, 350412, 350421, 351024, 351042, 351204, 351240, 351402, 351420, 352014,
352041, 352104, 352140, 352401, 352410, 354012, 354021, 354102, 354120, 354201, 354210, 401235, 401253,
401325, 401352, 401523, 401532, 402135, 402153, 402315, 402351, 402513, 402531, 403125, 403152, 403215,
403251, 403512, 403521, 405123, 405132, 405213, 405231, 405312, 405321, 410235, 410253, 410325, 410352,
410523, 410532, 412035, 412053, 412305, 412350, 412503, 412530, 413025, 413052, 413205, 413250, 413502,
413520, 415023, 415032, 415203, 415230, 415302, 415320, 420135, 420153, 420315, 420351, 420513, 420531,
421035, 421053, 421305, 421350, 421503, 421530, 423015, 423051, 423105, 423150, 423501, 423510, 425013,
425031, 425103, 425130, 425301, 425310, 430125, 430152, 430215, 430251, 430512, 430521, 431025, 431052,
431205, 431250, 431502, 431520, 432015, 432051, 432105, 432150, 432501, 432510, 435012, 435021, 435102,
435120, 435201, 435210, 450123, 450132, 450213, 450231, 450312, 450321, 451023, 451032, 451203, 451230,
451302, 451320, 452013, 452031, 452103, 452130, 452301, 452310, 453012, 453021, 453102, 453120, 453201,
453210, 501234, 501243, 501324, 501342, 501423, 501432, 502134, 502143, 502314, 502341, 502413, 502431,
503124, 503142, 503214, 503241, 503412, 503421, 504123, 504132, 504213, 504231, 504312, 504321, 510234,
510243, 510324, 510342, 510423, 510432, 512034, 512043, 512304, 512340, 512403, 512430, 513024, 513042,
513204, 513240, 513402, 513420, 514023, 514032, 514203, 514230, 514302, 514320, 520134, 520143, 520314,
520341, 520413, 520431, 521034, 521043, 521304, 521340, 521403, 521430, 523014, 523041, 523104, 523140,
523401, 523410, 524013, 524031, 524103, 524130, 524301, 524310, 530124, 530142, 530214, 530241, 530412,
530421, 531024, 531042, 531204, 531240, 531402, 531420, 532014, 532041, 532104, 532140, 532401, 532410,
534012, 534021, 534102, 534120, 534201, 534210, 540123, 540132, 540213, 540231, 540312, 540321, 541023,
541032, 541203, 541230, 541302, 541320, 542013, 542031, 542103, 542130, 542301, 542310, 543012, 543021,
543102, 543120, 543201, 543210 };
public static int[] ans = { 15, -1, -1, 3, 15, -1, -1, 15, 3, -1, -1, 17, 17, -1, -1, 15, 13, -1, -1, 17, 13, -1,
-1, 7, -1, 21, 15, -1, -1, 13, 3, -1, -1, 11, 11, -1, -1, 9, 15, -1, -1, 15, 9, -1, -1, 15, 17, -1, 15, -1,
-1, 11, 19, -1, -1, 13, 17, -1, -1, 19, 13, -1, -1, 15, 13, -1, -1, 7, 9, -1, -1, 11, -1, 9, 13, -1, -1, 9,
17, -1, -1, 15, 7, -1, -1, 17, 7, -1, -1, 11, 19, -1, -1, 11, 11, -1, 17, -1, -1, 13, 11, -1, -1, 5, 13, -1,
-1, 15, 11, -1, -1, 15, 17, -1, -1, 11, 11, -1, -1, 15, 14, -1, -1, 2, 14, -1, -1, 14, 2, -1, -1, 16, 16,
-1, -1, 14, 12, -1, -1, 16, 12, -1, -1, 6, 13, -1, -1, 1, 13, -1, 2, -1, 1, 0, -1, -1, -1, 10, -1, -1, 11,
12, 10, -1, 11, 12, -1, -1, -1, 15, 3, -1, -1, 17, -1, 14, -1, -1, 15, 16, 14, -1, 15, 16, -1, -1, -1, 6,
-1, -1, 5, 4, 17, -1, -1, 15, 13, -1, 16, -1, 15, 16, -1, -1, -1, 16, -1, -1, 15, 14, 18, -1, 17, 18, -1,
-1, -1, 15, 13, -1, -1, 5, -1, 4, -1, -1, 3, 4, 12, -1, 13, 14, -1, -1, -1, 12, -1, -1, 13, 14, -1, 20, 16,
-1, -1, 12, 4, -1, -1, 12, 12, -1, -1, 8, 16, -1, -1, 14, 8, -1, -1, 16, 16, -1, -1, 19, 17, -1, -1, 13, -1,
14, -1, -1, 13, 14, 18, -1, 17, 18, -1, -1, -1, 18, -1, -1, 17, 18, 5, -1, -1, 13, 13, -1, 16, -1, 15, 14,
-1, -1, -1, 16, -1, -1, 15, 14, 8, -1, 7, 6, -1, -1, -1, 7, 15, -1, -1, 13, -1, 10, -1, -1, 11, 12, 6, -1,
5, 6, -1, -1, -1, 12, -1, -1, 13, 14, 9, -1, -1, 15, 15, -1, 18, -1, 19, 16, -1, -1, -1, 14, -1, -1, 13, 14,
10, -1, 9, 10, -1, -1, 14, -1, -1, 12, 18, -1, -1, 12, 16, -1, -1, 18, 12, -1, -1, 14, 14, -1, -1, 8, 10,
-1, -1, 12, 13, -1, -1, 13, 17, -1, 16, -1, 15, 14, -1, -1, -1, 16, -1, -1, 15, 16, 12, -1, 11, 12, -1, -1,
-1, 13, 15, -1, -1, 19, -1, 20, -1, -1, 19, 20, 14, -1, 13, 14, -1, -1, -1, 14, -1, -1, 13, 14, 11, -1, -1,
15, 15, -1, 14, -1, 15, 16, -1, -1, -1, 16, -1, -1, 17, 16, 10, -1, 9, 10, -1, -1, -1, 9, 11, -1, -1, 13,
-1, 14, -1, -1, 13, 14, 12, -1, 11, 10, -1, -1, -1, 14, -1, -1, 13, 12, -1, 8, 12, -1, -1, 8, 18, -1, -1,
14, 6, -1, -1, 18, 6, -1, -1, 10, 20, -1, -1, 10, 10, -1, -1, 7, 11, -1, -1, 7, -1, 4, -1, -1, 5, 6, 4, -1,
5, 6, -1, -1, -1, 8, -1, -1, 9, 10, 19, -1, -1, 15, 7, -1, 14, -1, 13, 14, -1, -1, -1, 10, -1, -1, 9, 8, 18,
-1, 19, 20, -1, -1, -1, 19, 7, -1, -1, 11, -1, 10, -1, -1, 9, 10, 18, -1, 19, 20, -1, -1, -1, 10, -1, -1, 9,
8, 21, -1, -1, 11, 11, -1, 10, -1, 9, 10, -1, -1, -1, 14, -1, -1, 13, 12, 18, -1, 19, 20, -1, -1, 16, -1,
-1, 12, 12, -1, -1, 6, 14, -1, -1, 16, 10, -1, -1, 14, 16, -1, -1, 10, 12, -1, -1, 14, 15, -1, -1, 13, 13,
-1, 16, -1, 15, 14, -1, -1, -1, 16, -1, -1, 15, 14, 14, -1, 13, 14, -1, -1, -1, 7, 15, -1, -1, 15, -1, 14,
-1, -1, 13, 14, 10, -1, 9, 8, -1, -1, -1, 16, -1, -1, 15, 16, 11, -1, -1, 15, 17, -1, 18, -1, 17, 18, -1,
-1, -1, 18, -1, -1, 17, 18, 12, -1, 11, 12, -1, -1, -1, 9, 13, -1, -1, 13, -1, 10, -1, -1, 11, 12, 8, -1, 7,
8, -1, -1, -1, 12, -1, -1, 13, 14 };
public static int slidingPuzzle(int[][] board) {
int from = board[0][0] * 100000 + board[0][1] * 10000 + board[0][2] * 1000 + board[1][0] * 100
+ board[1][1] * 10 + board[1][2];
return ans[find(from)];
}
public static int find(int num) {
int ans = 0;
int l = 0;
int r = status.length - 1;
int m = 0;
while (l <= r) {
m = (l + r) / 2;
if (status[m] == num) {
ans = m;
break;
} else if (status[m] > num) {
r = m - 1;
} else {
l = m + 1;
}
}
return ans;
}
}

@ -0,0 +1,34 @@
package class_2022_08_1_week;
// 找到数组中的水王数
// 本题来自大厂刷题班23节
// 为了讲述下一个题,才重新讲述这个题
// 比较简单
public class Code02_WaterKing {
public static int waterKing(int[] arr) {
int cand = 0;
int hp = 0;
for (int i = 0; i < arr.length; i++) {
if (hp == 0) {
cand = arr[i];
hp = 1;
} else if (arr[i] == cand) {
hp++;
} else {
hp--;
}
}
if (hp == 0) {
return -1;
}
hp = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == cand) {
hp++;
}
}
return hp > arr.length / 2 ? cand : -1;
}
}

@ -0,0 +1,145 @@
package class_2022_08_1_week;
import java.util.ArrayList;
// 设计一个数据结构,有效地找到给定子数组的 多数元素 。
// 子数组的 多数元素 是在子数组中出现 threshold 次数或次数以上的元素。
// 实现 MajorityChecker 类:
// MajorityChecker(int[] arr) 
// 会用给定的数组 arr  MajorityChecker 初始化。
// int query(int left, int right, int threshold) 
// 返回子数组中的元素  arr[left...right] 至少出现 threshold 次数
// 如果不存在这样的元素则返回 -1。
// 为了让同学们听懂这个题
// 才安排的水王问题重讲
// 测试链接 : https://leetcode.cn/problems/online-majority-element-in-subarray/
public class Code03_OnlineMajorityElementInSubarray {
class MajorityChecker {
SegmentTree st;
CountQuicker cq;
public MajorityChecker(int[] arr) {
st = new SegmentTree(arr);
cq = new CountQuicker(arr);
}
public int query(int left, int right, int threshold) {
int candidate = st.query(left, right);
return cq.realTimes(left, right, candidate) >= threshold ? candidate : -1;
}
class SegmentTree {
int n;
int[] candidate;
int[] hp;
public SegmentTree(int[] arr) {
n = arr.length;
candidate = new int[(n + 1) << 2];
hp = new int[(n + 1) << 2];
build(arr, 1, n, 1);
}
private void build(int[] arr, int l, int r, int rt) {
if (l == r) {
candidate[rt] = arr[l - 1];
hp[rt] = 1;
} else {
int m = (l + r) >> 1;
build(arr, l, m, rt << 1);
build(arr, m + 1, r, rt << 1 | 1);
int lc = candidate[rt << 1];
int rc = candidate[rt << 1 | 1];
int lh = hp[rt << 1];
int rh = hp[rt << 1 | 1];
if (lc == rc) {
candidate[rt] = lc;
hp[rt] = lh + rh;
} else {
candidate[rt] = lh >= rh ? lc : rc;
hp[rt] = Math.abs(lh - rh);
}
}
}
public int query(int left, int right) {
return query(left + 1, right + 1, 1, n, 1)[0];
}
private int[] query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return new int[] { candidate[rt], hp[rt] };
}
int m = (l + r) >> 1;
if (R <= m) {
return query(L, R, l, m, rt << 1);
} else if (L > m) {
return query(L, R, m + 1, r, rt << 1 | 1);
} else {
int[] ansl = query(L, R, l, m, rt << 1);
int[] ansr = query(L, R, m + 1, r, rt << 1 | 1);
if (ansl[0] == ansr[0]) {
ansl[1] += ansr[1];
return ansl;
} else {
if (ansl[1] >= ansr[1]) {
ansl[1] -= ansr[1];
return ansl;
} else {
ansr[1] -= ansl[1];
return ansr;
}
}
}
}
}
class CountQuicker {
// v : i1 i14 i15
ArrayList<ArrayList<Integer>> cnt;
public CountQuicker(int[] arr) {
cnt = new ArrayList<>();
int max = 0;
for (int num : arr) {
max = Math.max(max, num);
}
for (int i = 0; i <= max; i++) {
cnt.add(new ArrayList<>());
}
for (int i = 0; i < arr.length; i++) {
cnt.get(arr[i]).add(i);
}
}
public int realTimes(int left, int right, int num) {
ArrayList<Integer> indies = cnt.get(num);
return size(indies, right) - size(indies, left - 1);
}
private int size(ArrayList<Integer> indies, int index) {
int l = 0;
int r = indies.size() - 1;
int m = 0;
int ans = -1;
while (l <= r) {
m = (l + r) / 2;
if (indies.get(m) <= index) {
ans = m;
l = m + 1;
} else {
r = m - 1;
}
}
return ans + 1;
}
}
}
}

@ -0,0 +1,37 @@
package class_2022_08_1_week;
import java.util.Arrays;
// 给你一个长度为 n 的整数数组 rolls 和一个整数 k 
// 你扔一个 k 面的骰子 n 骰子的每个面分别是 1  k 
// 其中第 i 次扔得到的数字是 rolls[i] 。
// 请你返回 无法 从 rolls 中得到的 最短 骰子子序列的长度。
// 扔一个 k 面的骰子 len 次得到的是一个长度为 len 的 骰子子序列 。
// 注意 ,子序列只需要保持在原数组中的顺序,不需要连续。
// 测试链接 : https://leetcode.cn/problems/shortest-impossible-sequence-of-rolls/
public class Code04_ShortestImpossibleSequenceOfRolls {
// 所有数字1~k
public static int shortestSequence(int[] rolls, int k) {
// 1~k上某个数字是否收集到了
// set[i] == true
// set[i] == false
boolean[] set = new boolean[k + 1];
// 当前这一套,收集了几个数字了?
int size = 0;
int ans = 0;
for (int num : rolls) {
if (!set[num]) {
set[num] = true;
size++;
}
if (size == k) {
ans++;
Arrays.fill(set, false);
size = 0;
}
}
return ans + 1;
}
}

@ -0,0 +1,103 @@
package class_2022_08_1_week;
// 给定一个只由小写字母和数字字符组成的字符串str
// 要求子串必须只含有一个小写字母,数字字符数量随意
// 求这样的子串最大长度是多少
public class Code05_LongestOneLetterManyNumberString {
// 一个绝对正确的暴力方法
public static int right(String s) {
char[] str = s.toCharArray();
int ans = 0;
for (int i = 0; i < str.length; i++) {
for (int j = i; j < str.length; j++) {
if (check(str, i, j)) {
ans = Math.max(ans, j - i + 1);
}
}
}
return ans;
}
public static boolean check(char[] str, int l, int r) {
int letterNumber = 0;
for (int i = l; i <= r; i++) {
if (str[i] >= 'a' && str[i] <= 'z') {
letterNumber++;
}
}
return letterNumber == 1;
}
// 用窗口
// 时间复杂度O(N)
public static int zuo(String s) {
char[] str = s.toCharArray();
int n = str.length;
// 窗口内有几个小写字母了
int letters = 0;
// 窗口的右边界
// [left, right)
int right = 0;
int ans = 0;
// for枚举了每一个窗口的开始位置0... 1...... 2.....
for (int left = 0; left < n; left++) {
while (right < n) { // right不能越界一旦越界不用再往右了
if (letters == 1 && str[right] >= 'a' && str[right] <= 'z') {
break;
}
// letters == 0 str[right]是数字
if (str[right] >= 'a' && str[right] <= 'z') {
letters++;
}
right++;
}
// [left.....right)
// [left.....right-1]
if (letters == 1) {
ans = Math.max(ans, right - left);
}
if (str[left] >= 'a' && str[left] <= 'z') {
letters--;
}
}
return ans;
}
// 为了测试
public static char[] chars = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z' };
// 为了测试
public static String randomString(int n) {
char[] str = new char[n];
for (int i = 0; i < n; i++) {
str[i] = chars[(int) (Math.random() * chars.length)];
}
return String.valueOf(str);
}
// 为了测试
public static void main(String[] args) {
int N = 100;
int testTimes = 10000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
String str = randomString(n);
int ans1 = right(str);
int ans2 = zuo(str);
if (ans1 != ans2) {
System.out.println(str);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("测试结束");
}
}

@ -0,0 +1,138 @@
package class_2022_08_1_week;
import java.util.Stack;
// 栈只提供push、pop、isEmpty三个方法
// 请完成无序栈的排序,要求排完序之后,从栈顶到栈底从小到大
// 只能使用栈提供的push、pop、isEmpty三个方法、以及递归函数
// 除此之外不能使用任何的容器,任何容器都不许,连数组也不行
// 也不能自己定义任何结构体
// 就是只用:
// 1) 栈提供的push、pop、isEmpty三个方法
// 2) 简单返回值的递归函数
public class Code06_SortStackUsingRecursive {
public static void sortStack(Stack<Integer> stack) {
int deep = deep(stack);
while (deep > 0) {
int max = max(stack, deep);
int k = times(stack, max, deep);
down(stack, deep, max, k);
deep -= k;
}
}
// 返回栈的深度
// 不改变栈的数据状况
// stack push pop isEmpty
public static int deep(Stack<Integer> stack) {
if (stack.isEmpty()) {
return 0;
}
int num = stack.pop();
int deep = deep(stack) + 1;
stack.push(num);
return deep;
}
// 从栈当前的顶部开始往下数deep层
// ) 返回这deep层里的最大值
public static int max(Stack<Integer> stack, int deep) {
if (deep == 0) {
return Integer.MIN_VALUE;
}
int num = stack.pop();
int restMax = max(stack, deep - 1);
int max = Math.max(num, restMax);
stack.push(num);
return max;
}
// 从栈当前的顶部开始往下数deep层已知最大值是max了
// 返回max出现了几次不改变栈的数据状况
public static int times(Stack<Integer> stack, int max, int deep) {
if (deep == 0) {
return 0;
}
int num = stack.pop();
int restTimes = times(stack, max, deep - 1);
int times = restTimes + (num == max ? 1 : 0);
stack.push(num);
return times;
}
// 从栈当前的顶部开始往下数deep层已知最大值是max出现了k次
// 请把这k个最大值沉底剩下的数据状况不变
public static void down(Stack<Integer> stack, int deep, int max, int k) {
if (deep == 0) {
for (int i = 0; i < k; i++) {
stack.push(max);
}
} else {
int num = stack.pop();
down(stack, deep - 1, max, k);
if (num != max) {
stack.push(num);
}
}
}
// 为了测试
// 生成随机栈
public static Stack<Integer> generateRandomStack(int n, int v) {
Stack<Integer> ans = new Stack<Integer>();
for (int i = 0; i < n; i++) {
ans.add((int) (Math.random() * v));
}
return ans;
}
// 为了测试
// 检测栈是不是有序的
public static boolean isSorted(Stack<Integer> stack) {
int step = Integer.MIN_VALUE;
while (!stack.isEmpty()) {
if (step > stack.peek()) {
return false;
}
step = stack.pop();
}
return true;
}
// 为了测试
public static void main(String[] args) {
Stack<Integer> test = new Stack<Integer>();
test.add(1);
test.add(5);
test.add(4);
test.add(5);
test.add(3);
test.add(2);
test.add(3);
test.add(1);
test.add(4);
test.add(2);
// 1 5 4 5 3 2 3 1 4 2
sortStack(test);
while (!test.isEmpty()) {
System.out.println(test.pop());
}
int N = 20;
int V = 20;
int testTimes = 20000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N);
Stack<Integer> stack = generateRandomStack(n, V);
sortStack(stack);
if (!isSorted(stack)) {
System.out.println("出错了!");
break;
}
}
System.out.println("测试结束");
}
}

@ -1486,3 +1486,57 @@ nums 中的 子集 是通过删除 nums 中一些可能一个都不删除
测试链接 : https://leetcode.cn/problems/the-number-of-good-subsets/
第034节 2022年8月第1周流行算法题目解析
在一个 2 * 3 的板上board有 5 块砖瓦,用数字 1~5 来表示,
以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字上下左右进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态 board 
返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
测试链接 : https://leetcode.cn/problems/sliding-puzzle/
找到数组中的水王数
本题来自大厂刷题班23节
为了讲述下一个题,才重新讲述这个题
比较简单
设计一个数据结构,有效地找到给定子数组的 多数元素 。
子数组的 多数元素 是在子数组中出现 threshold 次数或次数以上的元素。
实现 MajorityChecker 类:
MajorityChecker(int[] arr) 
会用给定的数组 arr  MajorityChecker 初始化。
int query(int left, int right, int threshold) 
返回子数组中的元素  arr[left...right] 至少出现 threshold 次数
如果不存在这样的元素则返回 -1。
为了让同学们听懂这个题
才安排的水王问题重讲
测试链接 : https://leetcode.cn/problems/online-majority-element-in-subarray/
给你一个长度为 n 的整数数组 rolls 和一个整数 k 
你扔一个 k 面的骰子 n 骰子的每个面分别是 1  k 
其中第 i 次扔得到的数字是 rolls[i] 。
请你返回 无法 从 rolls 中得到的 最短 骰子子序列的长度。
扔一个 k 面的骰子 len 次得到的是一个长度为 len 的 骰子子序列 。
注意 ,子序列只需要保持在原数组中的顺序,不需要连续。
测试链接 : https://leetcode.cn/problems/shortest-impossible-sequence-of-rolls/
给定一个只由小写字母和数字字符组成的字符串str
要求子串必须只含有一个小写字母,数字字符数量随意
求这样的子串最大长度是多少
栈只提供push、pop、isEmpty三个方法
请完成无序栈的排序,要求排完序之后,从栈顶到栈底从小到大
只能使用栈提供的push、pop、isEmpty三个方法、以及递归函数
除此之外不能使用任何的容器,任何容器都不许,连数组也不行
也不能自己定义任何结构体
就是只用:
1) 栈提供的push、pop、isEmpty三个方法
2) 简单返回值的递归函数

Loading…
Cancel
Save